Java tutorial
/* * Copyright (c) 2005-2011, 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.impl; import org.apache.axiom.om.OMAttribute; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.util.AXIOMUtil; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.entity.ContentType; import org.apache.solr.client.solrj.util.ClientUtils; import org.json.JSONException; import org.json.XML; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import org.wso2.carbon.CarbonConstants; import org.wso2.carbon.apimgt.api.APIManagementException; import org.wso2.carbon.apimgt.api.APIManager; import org.wso2.carbon.apimgt.api.APIMgtResourceAlreadyExistsException; import org.wso2.carbon.apimgt.api.APIMgtResourceNotFoundException; import org.wso2.carbon.apimgt.api.APIProvider; import org.wso2.carbon.apimgt.api.ApplicationNameWhiteSpaceValidationException; import org.wso2.carbon.apimgt.api.ApplicationNameWithInvalidCharactersException; import org.wso2.carbon.apimgt.api.BlockConditionNotFoundException; import org.wso2.carbon.apimgt.api.PolicyNotFoundException; import org.wso2.carbon.apimgt.api.model.API; import org.wso2.carbon.apimgt.api.model.APIIdentifier; import org.wso2.carbon.apimgt.api.model.APIKey; import org.wso2.carbon.apimgt.api.model.APIProduct; import org.wso2.carbon.apimgt.api.model.APIProductIdentifier; import org.wso2.carbon.apimgt.api.model.APIProductResource; import org.wso2.carbon.apimgt.api.model.AccessTokenInfo; import org.wso2.carbon.apimgt.api.model.Application; import org.wso2.carbon.apimgt.api.model.Documentation; import org.wso2.carbon.apimgt.api.model.DocumentationType; import org.wso2.carbon.apimgt.api.model.Identifier; import org.wso2.carbon.apimgt.api.model.KeyManager; import org.wso2.carbon.apimgt.api.model.Mediation; import org.wso2.carbon.apimgt.api.model.OAuthApplicationInfo; import org.wso2.carbon.apimgt.api.model.ResourceFile; import org.wso2.carbon.apimgt.api.model.Scope; import org.wso2.carbon.apimgt.api.model.SubscribedAPI; import org.wso2.carbon.apimgt.api.model.Subscriber; import org.wso2.carbon.apimgt.api.model.Tier; import org.wso2.carbon.apimgt.api.model.Wsdl; import org.wso2.carbon.apimgt.api.model.policy.Policy; import org.wso2.carbon.apimgt.api.model.policy.PolicyConstants; import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO; import org.wso2.carbon.apimgt.impl.definitions.OASParserUtil; import org.wso2.carbon.apimgt.impl.dto.ThrottleProperties; import org.wso2.carbon.apimgt.impl.factory.KeyManagerHolder; import org.wso2.carbon.apimgt.impl.indexing.indexer.DocumentIndexer; import org.wso2.carbon.apimgt.impl.internal.ServiceReferenceHolder; import org.wso2.carbon.apimgt.impl.utils.APINameComparator; import org.wso2.carbon.apimgt.impl.utils.APIProductNameComparator; import org.wso2.carbon.apimgt.impl.utils.APIUtil; import org.wso2.carbon.apimgt.impl.utils.ContentSearchResultNameComparator; import org.wso2.carbon.apimgt.impl.utils.LRUCache; import org.wso2.carbon.apimgt.impl.utils.TierNameComparator; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.governance.api.common.dataobjects.GovernanceArtifact; import org.wso2.carbon.governance.api.exception.GovernanceException; import org.wso2.carbon.governance.api.generic.GenericArtifactManager; import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact; import org.wso2.carbon.governance.api.util.GovernanceUtils; import org.wso2.carbon.registry.common.ResourceData; import org.wso2.carbon.registry.core.ActionConstants; import org.wso2.carbon.registry.core.Association; import org.wso2.carbon.registry.core.Collection; import org.wso2.carbon.registry.core.Registry; import org.wso2.carbon.registry.core.RegistryConstants; import org.wso2.carbon.registry.core.Resource; import org.wso2.carbon.registry.core.config.RegistryContext; import org.wso2.carbon.registry.core.exceptions.RegistryException; import org.wso2.carbon.registry.core.jdbc.realm.RegistryAuthorizationManager; import org.wso2.carbon.registry.core.pagination.PaginationContext; import org.wso2.carbon.registry.core.service.RegistryService; import org.wso2.carbon.registry.core.session.UserRegistry; import org.wso2.carbon.registry.core.utils.RegistryUtils; import org.wso2.carbon.registry.indexing.RegistryConfigLoader; import org.wso2.carbon.registry.indexing.indexer.Indexer; import org.wso2.carbon.registry.indexing.indexer.IndexerException; import org.wso2.carbon.registry.indexing.service.ContentBasedSearchService; import org.wso2.carbon.registry.indexing.service.SearchResultsBean; import org.wso2.carbon.user.api.AuthorizationManager; import org.wso2.carbon.user.core.UserRealm; import org.wso2.carbon.user.core.UserStoreException; import org.wso2.carbon.user.core.tenant.TenantManager; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import org.wso2.carbon.utils.multitenancy.MultitenantUtils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import java.net.URLDecoder; /** * The basic abstract implementation of the core APIManager interface. This implementation uses * the governance system registry for storing APIs and related metadata. */ public abstract class AbstractAPIManager implements APIManager { // API definitions from swagger v2.0 protected Log log = LogFactory.getLog(getClass()); protected Registry registry; protected UserRegistry configRegistry; protected ApiMgtDAO apiMgtDAO; protected int tenantId = MultitenantConstants.INVALID_TENANT_ID; //-1 the issue does not occur.; protected String tenantDomain; protected String username; // Property to indicate whether access control restriction feature is enabled. protected boolean isAccessControlRestrictionEnabled = false; private LRUCache<String, GenericArtifactManager> genericArtifactCache = new LRUCache<String, GenericArtifactManager>( 5); public AbstractAPIManager() throws APIManagementException { } public AbstractAPIManager(String username) throws APIManagementException { apiMgtDAO = ApiMgtDAO.getInstance(); try { if (username == null) { this.registry = getRegistryService().getGovernanceUserRegistry(); this.configRegistry = getRegistryService().getConfigSystemRegistry(); this.username = CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME; ServiceReferenceHolder .setUserRealm((ServiceReferenceHolder.getInstance().getRealmService().getBootstrapRealm())); } else { String tenantDomainName = MultitenantUtils.getTenantDomain(username); String tenantUserName = getTenantAwareUsername(username); int tenantId = getTenantManager().getTenantId(tenantDomainName); this.tenantId = tenantId; this.tenantDomain = tenantDomainName; this.username = tenantUserName; loadTenantRegistry(tenantId); this.registry = getRegistryService().getGovernanceUserRegistry(tenantUserName, tenantId); this.configRegistry = getRegistryService().getConfigSystemRegistry(tenantId); //load resources for each tenants. APIUtil.loadloadTenantAPIRXT(tenantUserName, tenantId); APIUtil.loadTenantAPIPolicy(tenantUserName, tenantId); //Check whether GatewayType is "Synapse" before attempting to load Custom-Sequences into registry APIManagerConfiguration configuration = getAPIManagerConfiguration(); String gatewayType = configuration.getFirstProperty(APIConstants.API_GATEWAY_TYPE); if (APIConstants.API_GATEWAY_TYPE_SYNAPSE.equalsIgnoreCase(gatewayType)) { APIUtil.writeDefinedSequencesToTenantRegistry(tenantId); } ServiceReferenceHolder.setUserRealm((UserRealm) (ServiceReferenceHolder.getInstance() .getRealmService().getTenantUserRealm(tenantId))); } ServiceReferenceHolder.setUserRealm(getRegistryService().getConfigSystemRegistry().getUserRealm()); registerCustomQueries(configRegistry, username); } catch (RegistryException e) { String msg = "Error while obtaining registry objects"; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Error while getting user registry for user:" + username; log.error(msg, e); throw new APIManagementException(msg, e); } } /** * method to register custom registry queries * * @param registry Registry instance to use * @throws RegistryException n error */ protected void registerCustomQueries(UserRegistry registry, String username) throws RegistryException, APIManagementException { String tagsQueryPath = RegistryConstants.QUERIES_COLLECTION_PATH + "/tag-summary"; String latestAPIsQueryPath = RegistryConstants.QUERIES_COLLECTION_PATH + "/latest-apis"; String resourcesByTag = RegistryConstants.QUERIES_COLLECTION_PATH + "/resource-by-tag"; String path = RegistryUtils.getAbsolutePath(RegistryContext.getBaseInstance(), APIUtil.getMountedPath(RegistryContext.getBaseInstance(), RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH) + APIConstants.GOVERNANCE_COMPONENT_REGISTRY_LOCATION); if (username == null) { try { UserRealm realm = ServiceReferenceHolder.getUserRealm(); RegistryAuthorizationManager authorizationManager = new RegistryAuthorizationManager(realm); authorizationManager.authorizeRole(APIConstants.ANONYMOUS_ROLE, path, ActionConstants.GET); } catch (UserStoreException e) { String msg = "Error while setting the permissions"; log.error(msg, e); throw new APIManagementException(msg, e); } } else if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { int tenantId; try { tenantId = getTenantManager().getTenantId(tenantDomain); AuthorizationManager authManager = ServiceReferenceHolder.getInstance().getRealmService() .getTenantUserRealm(tenantId).getAuthorizationManager(); authManager.authorizeRole(APIConstants.ANONYMOUS_ROLE, path, ActionConstants.GET); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Error while setting the permissions"; log.error(msg, e); throw new APIManagementException(msg, e); } } if (!registry.resourceExists(tagsQueryPath)) { Resource resource = registry.newResource(); //Tag Search Query //'MOCK_PATH' used to bypass ChrootWrapper -> filterSearchResult. A valid registry path is // a must for executeQuery results to be passed to client side String sql1 = "SELECT '" + APIUtil.getMountedPath(RegistryContext.getBaseInstance(), RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH) + APIConstants.GOVERNANCE_COMPONENT_REGISTRY_LOCATION + "' AS MOCK_PATH, " + " RT.REG_TAG_NAME AS TAG_NAME, " + " COUNT(RT.REG_TAG_NAME) AS USED_COUNT " + "FROM " + " REG_RESOURCE_TAG RRT, " + " REG_TAG RT, " + " REG_RESOURCE R, " + " REG_RESOURCE_PROPERTY RRP, " + " REG_PROPERTY RP " + "WHERE " + " RT.REG_ID = RRT.REG_TAG_ID " + " AND R.REG_MEDIA_TYPE = 'application/vnd.wso2-api+xml' " + " AND RRT.REG_VERSION = R.REG_VERSION " + " AND RRP.REG_VERSION = R.REG_VERSION " + " AND RP.REG_NAME = 'STATUS' " + " AND RRP.REG_PROPERTY_ID = RP.REG_ID " + " AND (RP.REG_VALUE !='DEPRECATED' AND RP.REG_VALUE !='CREATED' AND RP.REG_VALUE !='BLOCKED' AND RP.REG_VALUE !='RETIRED') " + "GROUP BY " + " RT.REG_TAG_NAME"; resource.setContent(sql1); resource.setMediaType(RegistryConstants.SQL_QUERY_MEDIA_TYPE); resource.addProperty(RegistryConstants.RESULT_TYPE_PROPERTY_NAME, RegistryConstants.TAG_SUMMARY_RESULT_TYPE); registry.put(tagsQueryPath, resource); } if (!registry.resourceExists(latestAPIsQueryPath)) { //Recently added APIs Resource resource = registry.newResource(); String sql = "SELECT " + " RR.REG_PATH_ID AS REG_PATH_ID, " + " RR.REG_NAME AS REG_NAME " + "FROM " + " REG_RESOURCE RR, " + " REG_RESOURCE_PROPERTY RRP, " + " REG_PROPERTY RP " + "WHERE " + " RR.REG_MEDIA_TYPE = 'application/vnd.wso2-api+xml' " + " AND RRP.REG_VERSION = RR.REG_VERSION " + " AND RP.REG_NAME = 'STATUS' " + " AND RRP.REG_PROPERTY_ID = RP.REG_ID " + " AND (RP.REG_VALUE !='DEPRECATED' AND RP.REG_VALUE !='CREATED') " + "ORDER BY " + " RR.REG_LAST_UPDATED_TIME " + "DESC "; resource.setContent(sql); resource.setMediaType(RegistryConstants.SQL_QUERY_MEDIA_TYPE); resource.addProperty(RegistryConstants.RESULT_TYPE_PROPERTY_NAME, RegistryConstants.RESOURCES_RESULT_TYPE); registry.put(latestAPIsQueryPath, resource); } if (!registry.resourceExists(resourcesByTag)) { Resource resource = registry.newResource(); String sql = "SELECT '" + APIUtil.getMountedPath(RegistryContext.getBaseInstance(), RegistryConstants.GOVERNANCE_REGISTRY_BASE_PATH) + APIConstants.GOVERNANCE_COMPONENT_REGISTRY_LOCATION + "' AS MOCK_PATH, " + " R.REG_UUID AS REG_UUID " + "FROM " + " REG_RESOURCE_TAG RRT, " + " REG_TAG RT, " + " REG_RESOURCE R, " + " REG_PATH RP " + "WHERE " + " RT.REG_TAG_NAME = ? " + " AND R.REG_MEDIA_TYPE = 'application/vnd.wso2-api+xml' " + " AND RP.REG_PATH_ID = R.REG_PATH_ID " + " AND RT.REG_ID = RRT.REG_TAG_ID " + " AND RRT.REG_VERSION = R.REG_VERSION "; resource.setContent(sql); resource.setMediaType(RegistryConstants.SQL_QUERY_MEDIA_TYPE); resource.addProperty(RegistryConstants.RESULT_TYPE_PROPERTY_NAME, RegistryConstants.RESOURCE_UUID_RESULT_TYPE); registry.put(resourcesByTag, resource); } } public void cleanup() { } public List<API> getAllAPIs() throws APIManagementException { List<API> apiSortedList = new ArrayList<API>(); boolean isTenantFlowStarted = false; try { if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { isTenantFlowStarted = true; startTenantFlow(tenantDomain); } GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_KEY); GenericArtifact[] artifacts = artifactManager.getAllGenericArtifacts(); for (GenericArtifact artifact : artifacts) { API api = null; try { api = APIUtil.getAPI(artifact); if (api != null) { try { checkAccessControlPermission(api.getId()); } catch (APIManagementException e) { // This is a second level of filter to get apis based on access control and visibility. // Hence log is set as debug and continued. if (log.isDebugEnabled()) { log.debug("User is not authorized to view the api " + api.getId().getApiName(), e); } continue; } } } catch (APIManagementException e) { //log and continue since we want to load the rest of the APIs. log.error("Error while loading API " + artifact.getAttribute(APIConstants.API_OVERVIEW_NAME), e); } if (api != null) { apiSortedList.add(api); } } } catch (RegistryException e) { String msg = "Failed to get APIs from the registry"; log.error(msg, e); throw new APIManagementException(msg, e); } finally { if (isTenantFlowStarted) { endTenantFlow(); } } Collections.sort(apiSortedList, new APINameComparator()); return apiSortedList; } /** * To check authorization of the API against current logged in user. If the user is not authorized an exception * will be thrown. * * @param identifier API identifier * @throws APIManagementException APIManagementException */ protected void checkAccessControlPermission(Identifier identifier) throws APIManagementException { // Implementation different based on invocation come from publisher or store } protected API getApi(GovernanceArtifact artifact) throws APIManagementException { return APIUtil.getAPI(artifact); } public API getAPI(APIIdentifier identifier) throws APIManagementException { String apiPath = APIUtil.getAPIPath(identifier); Registry registry; try { String apiTenantDomain = getTenantDomain(identifier); int apiTenantId = getTenantManager().getTenantId(apiTenantDomain); if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(apiTenantDomain)) { APIUtil.loadTenantRegistry(apiTenantId); } if (this.tenantDomain == null || !this.tenantDomain.equals(apiTenantDomain)) { //cross tenant scenario registry = getRegistryService().getGovernanceUserRegistry( getTenantAwareUsername(APIUtil.replaceEmailDomainBack(identifier.getProviderName())), apiTenantId); } else { registry = this.registry; } GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_KEY); Resource apiResource = registry.get(apiPath); String artifactId = apiResource.getUUID(); if (artifactId == null) { throw new APIManagementException("artifact id is null for : " + apiPath); } GenericArtifact apiArtifact = artifactManager.getGenericArtifact(artifactId); API api = APIUtil.getAPIForPublishing(apiArtifact, registry); //check for API visibility if (APIConstants.API_GLOBAL_VISIBILITY.equals(api.getVisibility())) { //global api return api; } if (this.tenantDomain == null || !this.tenantDomain.equals(apiTenantDomain)) { throw new APIManagementException( "User " + username + " does not have permission to view API : " + api.getId().getApiName()); } return api; } catch (RegistryException e) { String msg = "Failed to get API from : " + apiPath; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get API from : " + apiPath; log.error(msg, e); throw new APIManagementException(msg, e); } } protected String getTenantAwareUsername(String username) { return MultitenantUtils.getTenantAwareUsername(username); } protected String getTenantDomain(Identifier identifier) { return MultitenantUtils.getTenantDomain(APIUtil.replaceEmailDomainBack(identifier.getProviderName())); } protected API getApiForPublishing(Registry registry, GovernanceArtifact apiArtifact) throws APIManagementException { return APIUtil.getAPIForPublishing(apiArtifact, registry); } protected void loadTenantRegistry(int apiTenantId) throws RegistryException { APIUtil.loadTenantRegistry(apiTenantId); } /** * Get API by registry artifact id * * @param uuid Registry artifact id * @param requestedTenantDomain tenantDomain for the registry * @return API of the provided artifact id * @throws APIManagementException */ public API getAPIbyUUID(String uuid, String requestedTenantDomain) throws APIManagementException { try { Registry registry; if (requestedTenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(requestedTenantDomain)) { int id = getTenantManager().getTenantId(requestedTenantDomain); registry = getRegistryService().getGovernanceSystemRegistry(id); } else { if (this.tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(this.tenantDomain)) { // at this point, requested tenant = carbon.super but logged in user is anonymous or tenant registry = getRegistryService() .getGovernanceSystemRegistry(MultitenantConstants.SUPER_TENANT_ID); } else { // both requested tenant and logged in user's tenant are carbon.super registry = this.registry; } } GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_KEY); GenericArtifact apiArtifact = artifactManager.getGenericArtifact(uuid); if (apiArtifact != null) { return getApiForPublishing(registry, apiArtifact); } else { String msg = "Failed to get API. API artifact corresponding to artifactId " + uuid + " does not exist"; log.error(msg); throw new APIMgtResourceNotFoundException(msg); } } catch (RegistryException e) { String msg = "Failed to get API"; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get API"; log.error(msg, e); throw new APIManagementException(msg, e); } } protected TenantManager getTenantManager() { return ServiceReferenceHolder.getInstance().getRealmService().getTenantManager(); } /** * Get minimal details of API by registry artifact id * * @param uuid Registry artifact id * @return API of the provided artifact id * @throws APIManagementException */ public API getLightweightAPIByUUID(String uuid, String requestedTenantDomain) throws APIManagementException { try { Registry registry; if (requestedTenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(requestedTenantDomain)) { int id = getTenantManager().getTenantId(requestedTenantDomain); registry = getRegistryService().getGovernanceSystemRegistry(id); } else { if (this.tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(this.tenantDomain)) { // at this point, requested tenant = carbon.super but logged in user is anonymous or tenant registry = getRegistryService() .getGovernanceSystemRegistry(MultitenantConstants.SUPER_TENANT_ID); } else { // both requested tenant and logged in user's tenant are carbon.super registry = this.registry; } } GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_KEY); GenericArtifact apiArtifact = artifactManager.getGenericArtifact(uuid); if (apiArtifact != null) { return getApiInformation(registry, apiArtifact); } else { String msg = "Failed to get API. API artifact corresponding to artifactId " + uuid + " does not exist"; log.error(msg); throw new APIMgtResourceNotFoundException(msg); } } catch (RegistryException e) { String msg = "Failed to get API with uuid " + uuid; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get tenant Id while getting API with uuid " + uuid; log.error(msg, e); throw new APIManagementException(msg, e); } } protected API getApiInformation(Registry registry, GovernanceArtifact apiArtifact) throws APIManagementException { return APIUtil.getAPIInformation(apiArtifact, registry); } /** * Get minimal details of API by API identifier * * @param identifier APIIdentifier object * @return API of the provided APIIdentifier * @throws APIManagementException */ public API getLightweightAPI(APIIdentifier identifier) throws APIManagementException { String apiPath = APIUtil.getAPIPath(identifier); boolean tenantFlowStarted = false; try { String tenantDomain = getTenantDomain(identifier); startTenantFlow(tenantDomain); tenantFlowStarted = true; Registry registry = getRegistry(identifier, apiPath); if (registry != null) { Resource apiResource = registry.get(apiPath); String artifactId = apiResource.getUUID(); if (artifactId == null) { throw new APIManagementException("artifact id is null for : " + apiPath); } GenericArtifactManager artifactManager = getAPIGenericArtifactManager(identifier, registry); GovernanceArtifact apiArtifact = artifactManager.getGenericArtifact(artifactId); return getApiInformation(registry, apiArtifact); } else { String msg = "Failed to get registry from api identifier: " + identifier; log.error(msg); throw new APIManagementException(msg); } } catch (RegistryException e) { String msg = "Failed to get API from : " + apiPath; log.error(msg, e); throw new APIManagementException(msg, e); } finally { if (tenantFlowStarted) { endTenantFlow(); } } } protected void endTenantFlow() { PrivilegedCarbonContext.endTenantFlow(); } protected void startTenantFlow(String tenantDomain) { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain, true); } private GenericArtifactManager getAPIGenericArtifactManager(APIIdentifier identifier, Registry registry) throws APIManagementException { String tenantDomain = getTenantDomain(identifier); GenericArtifactManager manager = genericArtifactCache.get(tenantDomain); if (manager != null) { return manager; } manager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_KEY); genericArtifactCache.put(tenantDomain, manager); return manager; } private Registry getRegistry(APIIdentifier identifier, String apiPath) throws APIManagementException { Registry passRegistry; try { String tenantDomain = getTenantDomain(identifier); if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { int id = getTenantManager().getTenantId(tenantDomain); // explicitly load the tenant's registry APIUtil.loadTenantRegistry(id); passRegistry = getRegistryService().getGovernanceSystemRegistry(id); } else { if (this.tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(this.tenantDomain)) { // explicitly load the tenant's registry APIUtil.loadTenantRegistry(MultitenantConstants.SUPER_TENANT_ID); passRegistry = getRegistryService().getGovernanceUserRegistry(identifier.getProviderName(), MultitenantConstants.SUPER_TENANT_ID); } else { passRegistry = this.registry; } } } catch (RegistryException e) { String msg = "Failed to get API from registry on path of : " + apiPath; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get API from registry on path of : " + apiPath; log.error(msg, e); throw new APIManagementException(msg, e); } return passRegistry; } public API getAPI(String apiPath) throws APIManagementException { try { GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_KEY); Resource apiResource = registry.get(apiPath); String artifactId = apiResource.getUUID(); if (artifactId == null) { throw new APIManagementException("artifact id is null for : " + apiPath); } GenericArtifact apiArtifact = artifactManager.getGenericArtifact(artifactId); return getApi(apiArtifact); } catch (RegistryException e) { String msg = "Failed to get API from : " + apiPath; log.error(msg, e); throw new APIManagementException(msg, e); } } public boolean isAPIAvailable(APIIdentifier identifier) throws APIManagementException { String path = APIConstants.API_ROOT_LOCATION + RegistryConstants.PATH_SEPARATOR + identifier.getProviderName() + RegistryConstants.PATH_SEPARATOR + identifier.getApiName() + RegistryConstants.PATH_SEPARATOR + identifier.getVersion(); try { return registry.resourceExists(path); } catch (RegistryException e) { String msg = "Failed to check availability of api :" + path; log.error(msg, e); throw new APIManagementException(msg, e); } } public Set<String> getAPIVersions(String providerName, String apiName) throws APIManagementException { Set<String> versionSet = new HashSet<String>(); String apiPath = APIConstants.API_LOCATION + RegistryConstants.PATH_SEPARATOR + providerName + RegistryConstants.PATH_SEPARATOR + apiName; try { Resource resource = registry.get(apiPath); if (resource instanceof Collection) { Collection collection = (Collection) resource; String[] versionPaths = collection.getChildren(); if (versionPaths == null || versionPaths.length == 0) { return versionSet; } for (String path : versionPaths) { versionSet.add(path.substring(apiPath.length() + 1)); } } else { throw new APIManagementException("API version must be a collection " + apiName); } } catch (RegistryException e) { String msg = "Failed to get versions for API: " + apiName; log.error(msg, e); throw new APIManagementException(msg, e); } return versionSet; } /** * Returns list of global mediation policies available * * @return List of Mediation objects of global mediation policies * @throws APIManagementException If failed to get global mediation policies */ @Override public List<Mediation> getAllGlobalMediationPolicies() throws APIManagementException { List<Mediation> mediationList = new ArrayList<Mediation>(); Mediation mediation; String resourcePath = APIConstants.API_CUSTOM_SEQUENCE_LOCATION; try { //Resource : customsequences Resource resource = registry.get(resourcePath); if (resource instanceof Collection) { Collection typeCollection = (Collection) resource; String[] typeArray = typeCollection.getChildren(); for (String type : typeArray) { //Resource : in / out / fault Resource typeResource = registry.get(type); if (typeResource instanceof Collection) { String[] sequenceArray = ((Collection) typeResource).getChildren(); if (sequenceArray.length > 0) { for (String sequence : sequenceArray) { //Resource : actual resource eg : log_in_msg.xml Resource sequenceResource = registry.get(sequence); String resourceId = sequenceResource.getUUID(); try { String contentString = IOUtils.toString(sequenceResource.getContentStream(), RegistryConstants.DEFAULT_CHARSET_ENCODING); OMElement omElement = AXIOMUtil.stringToOM(contentString); OMAttribute attribute = omElement .getAttribute(new QName(PolicyConstants.MEDIATION_NAME_ATTRIBUTE)); String mediationPolicyName = attribute.getAttributeValue(); mediation = new Mediation(); mediation.setUuid(resourceId); mediation.setName(mediationPolicyName); //Extract sequence type from the registry resource path String resourceType = type.substring(type.lastIndexOf("/") + 1); mediation.setType(resourceType); //Add mediation to the mediation list mediationList.add(mediation); } catch (XMLStreamException e) { //If any exception been caught flow may continue with the next mediation policy log.error("Error occurred while getting omElement out of " + "mediation content from " + sequence, e); } catch (IOException e) { log.error("Error occurred while converting resource " + "contentStream in to string in " + sequence, e); } } } } } } } catch (RegistryException e) { String msg = "Failed to get global mediation policies"; log.error(msg, e); throw new APIManagementException(msg, e); } return mediationList; } /** * Return mediation policy corresponds to the given identifier * * @param mediationPolicyId uuid of the registry resource * @return Mediation object related to the given identifier or null * @throws APIManagementException If failed to get specified mediation policy */ @Override public Mediation getGlobalMediationPolicy(String mediationPolicyId) throws APIManagementException { Mediation mediation = null; //Get registry resource correspond to identifier Resource mediationResource = this.getCustomMediationResourceFromUuid(mediationPolicyId); if (mediationResource != null) { //Get mediation config details try { //extracting content stream of mediation policy in to string String contentString = IOUtils.toString(mediationResource.getContentStream(), RegistryConstants.DEFAULT_CHARSET_ENCODING); //Get policy name from the mediation config OMElement omElement = AXIOMUtil.stringToOM(contentString); OMAttribute attribute = omElement.getAttribute(new QName(PolicyConstants.MEDIATION_NAME_ATTRIBUTE)); String mediationPolicyName = attribute.getAttributeValue(); mediation = new Mediation(); mediation.setUuid(mediationResource.getUUID()); mediation.setName(mediationPolicyName); String resourcePath = mediationResource.getPath(); //Extracting mediation type from the registry resource path String[] path = resourcePath.split(RegistryConstants.PATH_SEPARATOR); String resourceType = path[(path.length - 2)]; mediation.setType(resourceType); mediation.setConfig(contentString); } catch (RegistryException e) { log.error("Error occurred while getting content stream of the ,mediation policy ", e); } catch (IOException e) { log.error("Error occurred while converting content stream of mediation policy " + "into string ", e); } catch (XMLStreamException e) { log.error("Error occurred while getting omElement out of mediation content ", e); } } return mediation; } /** * Returns list of wsdls * * @return list of wsdl objects or null * @throws APIManagementException If unable to return satisfied wsdl object list */ @Override public List<Wsdl> getAllWsdls() throws APIManagementException { List<Wsdl> wsdlList = new ArrayList<Wsdl>(); String resourcePath = APIConstants.API_WSDL_RESOURCE; try { if (registry.resourceExists(resourcePath)) { Resource wsdlResource = registry.get(resourcePath); if (wsdlResource instanceof Collection) { String[] wsdlCollection = ((Collection) wsdlResource).getChildren(); if (wsdlCollection.length > 0) { for (String wsdlFile : wsdlCollection) { Resource wsdlResourceFile = registry.get(wsdlFile); String uuid = wsdlResourceFile.getUUID(); Wsdl wsdl = new Wsdl(); String wsdlName = wsdlFile.substring(wsdlFile.lastIndexOf("/") + 1); wsdl.setUuid(uuid); wsdl.setName(wsdlName); wsdlList.add(wsdl); } } } } } catch (RegistryException e) { String msg = "Failed to get wsdl list"; log.error(msg, e); throw new APIManagementException(msg, e); } return wsdlList; } /** * Return Wsdl specify by identifier * * @param wsdlId uuid of the wsdl resource * @return A Wsdl object related to the given identifier or null * @throws APIManagementException If failed to get specified wsdl */ @Override public Wsdl getWsdlById(String wsdlId) throws APIManagementException { Wsdl wsdl = null; //Get registry resource correspond to identifier Resource wsdlResource = this.getWsdlResourceFromUuid(wsdlId); if (wsdlResource != null) { try { //extracting content stream of wsdl in to string String contentString = IOUtils.toString(wsdlResource.getContentStream(), RegistryConstants.DEFAULT_CHARSET_ENCODING); wsdl = new Wsdl(); String resourcePath = wsdlResource.getPath(); String wsdlName = resourcePath.substring(resourcePath.lastIndexOf("/") + 1); wsdl.setUuid(wsdlResource.getUUID()); wsdl.setName(wsdlName); wsdl.setConfig(contentString); } catch (RegistryException e) { log.error("Error occurred while getting content stream of the wsdl " + wsdlResource.getPath(), e); } catch (IOException e) { log.error("Error occurred while converting content stream of wsdl " + wsdlResource.getPath() + " into string ", e); } } return wsdl; } /** * Returns the wsdl registry resource correspond to the given identifier * * @param wsdlId uuid of the wsdl resource * @return Registry resource of given identifier or null * @throws APIManagementException If failed to get the registry resource of given uuid */ @Override public Resource getWsdlResourceFromUuid(String wsdlId) throws APIManagementException { String resourcePath = APIConstants.API_WSDL_RESOURCE; try { if (registry.resourceExists(resourcePath)) { Resource resource = registry.get(resourcePath); //resource : /_system/governance/apimgt/applicationdata/wsdls if (resource instanceof Collection) { Collection wsdlCollection = (Collection) resource; String[] wsdlArray = wsdlCollection.getChildren(); for (String wsdl : wsdlArray) { Resource wsdlResource = registry.get(wsdl); String resourceId = wsdlResource.getUUID(); if (resourceId.equals(wsdlId)) { return wsdlResource; } } } } } catch (RegistryException e) { String msg = "Error while accessing registry objects"; log.error(msg, e); throw new APIManagementException(msg, e); } return null; } /** * Delete an existing wsdl * * @param wsdlId uuid of the wsdl * @return true if deleted successfully * @throws APIManagementException If failed to delete wsdl */ @Override public boolean deleteWsdl(String wsdlId) throws APIManagementException { //Get registry resource correspond to the uuid Resource wsdlResource = this.getWsdlResourceFromUuid(wsdlId); if (wsdlResource != null) { //If resource exists String wsdlResourcePath = wsdlResource.getPath(); try { if (registry.resourceExists(wsdlResourcePath)) { ////TODO : validation if wsdl been use by any API registry.delete(wsdlResourcePath); //Verify if deleted successfully if (!registry.resourceExists(wsdlResourcePath)) { if (log.isDebugEnabled()) { log.debug("Wsdl " + wsdlResourcePath + " deleted successfully"); } return true; } } } catch (RegistryException e) { String msg = "Failed to delete wsdl " + wsdlResourcePath; log.error(msg, e); throw new APIManagementException(msg, e); } } return false; } /** * Returns the wsdl content in registry specified by the wsdl name * * @param apiId Api Identifier * @return wsdl content matching name if exist else null */ @Override public String getWsdl(APIIdentifier apiId) throws APIManagementException { String wsdlDoc = null; String wsdlName = apiId.getProviderName() + "--" + apiId.getApiName() + apiId.getVersion() + ".wsdl"; String wsdlResourePath = APIConstants.API_WSDL_RESOURCE_LOCATION + wsdlName; try { if (registry.resourceExists(wsdlResourePath)) { Resource wsdlResource = registry.get(wsdlResourePath); wsdlDoc = IOUtils.toString(wsdlResource.getContentStream(), RegistryConstants.DEFAULT_CHARSET_ENCODING); } } catch (RegistryException e) { String msg = "Error while getting wsdl file from the registry "; log.error(msg, e); throw new APIManagementException(msg, e); } catch (IOException e) { String error = "Error occurred while getting the content of wsdl " + wsdlName; log.error(error); throw new APIManagementException(error, e); } return wsdlDoc; } /** * Create a wsdl in the path specified. * * @param resourcePath Registry path of the resource * @param wsdlDefinition wsdl content */ @Override public void uploadWsdl(String resourcePath, String wsdlDefinition) throws APIManagementException { try { Resource resource = registry.newResource(); resource.setContent(wsdlDefinition); resource.setMediaType(String.valueOf(ContentType.APPLICATION_XML)); registry.put(resourcePath, resource); } catch (RegistryException e) { String msg = "Error while uploading wsdl to from the registry "; log.error(msg, e); throw new APIManagementException(msg, e); } } /** * Update a existing wsdl in the path specified * * @param resourcePath Registry path of the resource * @param wsdlDefinition wsdl content */ @Override public void updateWsdl(String resourcePath, String wsdlDefinition) throws APIManagementException { try { Resource resource = registry.get(resourcePath); resource.setContent(wsdlDefinition); registry.put(resourcePath, resource); } catch (RegistryException e) { String msg = "Error while updating the existing wsdl "; log.error(msg, e); throw new APIManagementException(msg, e); } } /** * Returns the graphQL content in registry specified by the wsdl name * * @param apiId Api Identifier * @return graphQL content matching name if exist else null */ @Override public String getGraphqlSchema(APIIdentifier apiId) throws APIManagementException { String schemaDoc = null; String schemaName = apiId.getProviderName() + APIConstants.GRAPHQL_SCHEMA_PROVIDER_SEPERATOR + apiId.getApiName() + apiId.getVersion() + APIConstants.GRAPHQL_SCHEMA_FILE_EXTENSION; String schemaResourePath = APIConstants.API_GRAPHQL_SCHEMA_RESOURCE_LOCATION + schemaName; try { if (registry.resourceExists(schemaResourePath)) { Resource schemaResource = registry.get(schemaResourePath); schemaDoc = IOUtils.toString(schemaResource.getContentStream(), RegistryConstants.DEFAULT_CHARSET_ENCODING); } } catch (RegistryException e) { String msg = "Error while getting schema file from the registry " + schemaResourePath; log.error(msg, e); throw new APIManagementException(msg, e); } catch (IOException e) { String error = "Error occurred while getting the content of schema " + schemaName; log.error(error); throw new APIManagementException(error, e); } return schemaDoc; } /** * Create a graphql schema in the path specified. * * @param resourcePath Registry path of the resource * @param schemaDefinition wsdl content */ @Override public void uploadGraphqlSchema(String resourcePath, String schemaDefinition) throws APIManagementException { try { Resource resource; if (!registry.resourceExists(resourcePath)) { resource = registry.newResource(); } else { resource = registry.get(resourcePath); } resource.setContent(schemaDefinition); resource.setMediaType(String.valueOf(ContentType.TEXT_PLAIN)); registry.put(resourcePath, resource); if (log.isDebugEnabled()) { log.debug("Successfully imported the schema: " + schemaDefinition); } } catch (RegistryException e) { String msg = "Error while uploading schema to " + resourcePath + "in the registry"; log.error(msg, e); throw new APIManagementException(msg, e); } } /** * Returns the swagger 2.0 definition of the given API * * @param apiId id of the APIIdentifier * @return An String containing the swagger 2.0 definition * @throws APIManagementException */ @Override public String getOpenAPIDefinition(APIIdentifier apiId) throws APIManagementException { String apiTenantDomain = getTenantDomain(apiId); String swaggerDoc = null; try { Registry registryType; //Tenant store anonymous mode if current tenant and the required tenant is not matching if (this.tenantDomain == null || isTenantDomainNotMatching(apiTenantDomain)) { int tenantId = getTenantManager().getTenantId(apiTenantDomain); registryType = getRegistryService() .getGovernanceUserRegistry(CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME, tenantId); } else { registryType = registry; } swaggerDoc = OASParserUtil.getAPIDefinition(apiId, registryType); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get swagger documentation of API : " + apiId; log.error(msg, e); throw new APIManagementException(msg, e); } catch (RegistryException e) { String msg = "Failed to get swagger documentation of API : " + apiId; log.error(msg, e); throw new APIManagementException(msg, e); } return swaggerDoc; } public String addResourceFile(String resourcePath, ResourceFile resourceFile) throws APIManagementException { try { Resource thumb = registry.newResource(); thumb.setContentStream(resourceFile.getContent()); thumb.setMediaType(resourceFile.getContentType()); registry.put(resourcePath, thumb); if (MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equalsIgnoreCase(tenantDomain)) { return RegistryConstants.PATH_SEPARATOR + "registry" + RegistryConstants.PATH_SEPARATOR + "resource" + RegistryConstants.PATH_SEPARATOR + "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + resourcePath; } else { return "/t/" + tenantDomain + RegistryConstants.PATH_SEPARATOR + "registry" + RegistryConstants.PATH_SEPARATOR + "resource" + RegistryConstants.PATH_SEPARATOR + "_system" + RegistryConstants.PATH_SEPARATOR + "governance" + resourcePath; } } catch (RegistryException e) { String msg = "Error while adding the resource to the registry"; log.error(msg, e); throw new APIManagementException(msg, e); } } /** * Checks whether the given document already exists for the given api/product * * @param identifier API/Product Identifier * @param docName Name of the document * @return true if document already exists for the given api/product * @throws APIManagementException if failed to check existence of the documentation */ public boolean isDocumentationExist(Identifier identifier, String docName) throws APIManagementException { String docPath = ""; if (identifier instanceof APIIdentifier) { docPath = APIConstants.API_ROOT_LOCATION + RegistryConstants.PATH_SEPARATOR + identifier.getProviderName() + RegistryConstants.PATH_SEPARATOR + identifier.getName() + RegistryConstants.PATH_SEPARATOR + identifier.getVersion() + RegistryConstants.PATH_SEPARATOR + APIConstants.DOC_DIR + RegistryConstants.PATH_SEPARATOR + docName; } else if (identifier instanceof APIProductIdentifier) { docPath = APIConstants.API_APPLICATION_DATA_LOCATION + RegistryConstants.PATH_SEPARATOR + APIConstants.API_PRODUCT_RESOURCE_COLLECTION + RegistryConstants.PATH_SEPARATOR + identifier.getProviderName() + RegistryConstants.PATH_SEPARATOR + identifier.getName() + RegistryConstants.PATH_SEPARATOR + identifier.getVersion() + RegistryConstants.PATH_SEPARATOR + APIConstants.DOC_DIR + RegistryConstants.PATH_SEPARATOR + docName; } try { return registry.resourceExists(docPath); } catch (RegistryException e) { String msg = "Failed to check existence of the document :" + docPath; log.error(msg, e); throw new APIManagementException(msg, e); } } public List<Documentation> getAllDocumentation(Identifier id) throws APIManagementException { List<Documentation> documentationList = new ArrayList<Documentation>(); String resourcePath = StringUtils.EMPTY; String docArtifactKeyType = StringUtils.EMPTY; if (id instanceof APIIdentifier) { resourcePath = APIUtil.getAPIPath((APIIdentifier) id); docArtifactKeyType = APIConstants.DOCUMENTATION_KEY; } else if (id instanceof APIProductIdentifier) { resourcePath = APIUtil.getAPIProductPath((APIProductIdentifier) id); docArtifactKeyType = APIConstants.PRODUCT_DOCUMENTATION_KEY; } try { Association[] docAssociations = registry.getAssociations(resourcePath, APIConstants.DOCUMENTATION_ASSOCIATION); if (docAssociations == null) { return documentationList; } for (Association association : docAssociations) { String docPath = association.getDestinationPath(); Resource docResource = registry.get(docPath); GenericArtifactManager artifactManager = getAPIGenericArtifactManager(registry, docArtifactKeyType); GenericArtifact docArtifact = artifactManager.getGenericArtifact(docResource.getUUID()); Documentation doc = APIUtil.getDocumentation(docArtifact); Date contentLastModifiedDate; Date docLastModifiedDate = docResource.getLastModified(); if (Documentation.DocumentSourceType.INLINE.equals(doc.getSourceType()) || Documentation.DocumentSourceType.MARKDOWN.equals(doc.getSourceType())) { String contentPath = StringUtils.EMPTY; if (id instanceof APIIdentifier) { contentPath = APIUtil.getAPIDocContentPath((APIIdentifier) id, doc.getName()); } else if (id instanceof APIProductIdentifier) { contentPath = APIUtil.getProductDocContentPath((APIProductIdentifier) id, doc.getName()); } contentLastModifiedDate = registry.get(contentPath).getLastModified(); doc.setLastUpdated((contentLastModifiedDate.after(docLastModifiedDate) ? contentLastModifiedDate : docLastModifiedDate)); } else { doc.setLastUpdated(docLastModifiedDate); } documentationList.add(doc); } } catch (RegistryException e) { String msg = "Failed to get documentations for api/product " + id.getName(); log.error(msg, e); throw new APIManagementException(msg, e); } return documentationList; } public List<Documentation> getAllDocumentation(APIIdentifier apiId, String loggedUsername) throws APIManagementException { List<Documentation> documentationList = new ArrayList<Documentation>(); String apiResourcePath = APIUtil.getAPIPath(apiId); try { String tenantDomain = getTenantDomain(apiId); Registry registryType; /* If the API provider is a tenant, load tenant registry*/ boolean isTenantMode = (tenantDomain != null); if ((isTenantMode && this.tenantDomain == null) || (isTenantMode && isTenantDomainNotMatching(tenantDomain))) {//Tenant store anonymous mode int tenantId = getTenantManager().getTenantId(tenantDomain); registryType = getRegistryService() .getGovernanceUserRegistry(CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME, tenantId); } else { registryType = registry; } Association[] docAssociations = registryType.getAssociations(apiResourcePath, APIConstants.DOCUMENTATION_ASSOCIATION); for (Association association : docAssociations) { String docPath = association.getDestinationPath(); Resource docResource = null; try { docResource = registryType.get(docPath); } catch (org.wso2.carbon.registry.core.secure.AuthorizationFailedException e) { //do nothing. Permission not allowed to access the doc. } catch (RegistryException e) { String msg = "Failed to get documentations for api " + apiId.getApiName(); log.error(msg, e); throw new APIManagementException(msg, e); } if (docResource != null) { GenericArtifactManager artifactManager = getAPIGenericArtifactManager(registryType, APIConstants.DOCUMENTATION_KEY); GenericArtifact docArtifact = artifactManager.getGenericArtifact(docResource.getUUID()); Documentation doc = APIUtil.getDocumentation(docArtifact, apiId.getProviderName()); Date contentLastModifiedDate; Date docLastModifiedDate = docResource.getLastModified(); if (Documentation.DocumentSourceType.INLINE.equals(doc.getSourceType())) { String contentPath = APIUtil.getAPIDocContentPath(apiId, doc.getName()); try { contentLastModifiedDate = registryType.get(contentPath).getLastModified(); doc.setLastUpdated( (contentLastModifiedDate.after(docLastModifiedDate) ? contentLastModifiedDate : docLastModifiedDate)); } catch (org.wso2.carbon.registry.core.secure.AuthorizationFailedException e) { //do nothing. Permission not allowed to access the doc. } } else if (Documentation.DocumentSourceType.MARKDOWN.equals(doc.getSourceType())) { String contentPath = APIUtil.getAPIDocContentPath(apiId, doc.getName()); try { contentLastModifiedDate = registryType.get(contentPath).getLastModified(); doc.setLastUpdated( (contentLastModifiedDate.after(docLastModifiedDate) ? contentLastModifiedDate : docLastModifiedDate)); } catch (org.wso2.carbon.registry.core.secure.AuthorizationFailedException e) { //do nothing. Permission not allowed to access the doc. } } else { doc.setLastUpdated(docLastModifiedDate); } documentationList.add(doc); } } } catch (RegistryException e) { String msg = "Failed to get documentations for api " + apiId.getApiName(); log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get documentations for api " + apiId.getApiName(); log.error(msg, e); throw new APIManagementException(msg, e); } return documentationList; } protected GenericArtifactManager getAPIGenericArtifactManager(Registry registryType, String keyType) throws APIManagementException { try { return new GenericArtifactManager(registryType, keyType); } catch (RegistryException e) { handleException("Error while retrieving generic artifact manager object", e); } return null; } protected GenericArtifactManager getAPIGenericArtifactManagerFromUtil(Registry registry, String keyType) throws APIManagementException { return APIUtil.getArtifactManager(registry, keyType); } private boolean isTenantDomainNotMatching(String tenantDomain) { if (this.tenantDomain != null) { return !(this.tenantDomain.equals(tenantDomain)); } return true; } public Documentation getDocumentation(APIIdentifier apiId, DocumentationType docType, String docName) throws APIManagementException { Documentation documentation = null; String docPath = APIUtil.getAPIDocPath(apiId) + docName; GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.DOCUMENTATION_KEY); try { Resource docResource = registry.get(docPath); GenericArtifact artifact = artifactManager.getGenericArtifact(docResource.getUUID()); documentation = APIUtil.getDocumentation(artifact); } catch (RegistryException e) { String msg = "Failed to get documentation details"; log.error(msg, e); throw new APIManagementException(msg, e); } return documentation; } /** * Get a documentation by artifact Id * * @param docId artifact id of the document * @param requestedTenantDomain tenant domain of the registry where the artifact is located * @return Document object which represents the artifact id * @throws APIManagementException */ public Documentation getDocumentation(String docId, String requestedTenantDomain) throws APIManagementException { Documentation documentation = null; try { Registry registryType; boolean isTenantMode = (requestedTenantDomain != null); //Tenant store anonymous mode if current tenant and the required tenant is not matching if ((isTenantMode && this.tenantDomain == null) || (isTenantMode && isTenantDomainNotMatching(requestedTenantDomain))) { int tenantId = getTenantManager().getTenantId(requestedTenantDomain); registryType = getRegistryService() .getGovernanceUserRegistry(CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME, tenantId); } else { registryType = registry; } GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registryType, APIConstants.DOCUMENTATION_KEY); GenericArtifact artifact = artifactManager.getGenericArtifact(docId); APIIdentifier apiIdentifier = APIUtil.getAPIIdentifier(artifact.getPath()); checkAccessControlPermission(apiIdentifier); if (null != artifact) { documentation = APIUtil.getDocumentation(artifact); documentation.setCreatedDate(registryType.get(artifact.getPath()).getCreatedTime()); Date lastModified = registryType.get(artifact.getPath()).getLastModified(); if (lastModified != null) { documentation.setLastUpdated(registryType.get(artifact.getPath()).getLastModified()); } } } catch (RegistryException e) { String msg = "Failed to get documentation details"; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get documentation details"; log.error(msg, e); throw new APIManagementException(msg, e); } return documentation; } public String getDocumentationContent(Identifier identifier, String documentationName) throws APIManagementException { String contentPath = StringUtils.EMPTY; String identifierType = StringUtils.EMPTY; if (identifier instanceof APIIdentifier) { contentPath = APIUtil.getAPIDocPath((APIIdentifier) identifier) + APIConstants.INLINE_DOCUMENT_CONTENT_DIR + RegistryConstants.PATH_SEPARATOR + documentationName; identifierType = APIConstants.API_IDENTIFIER_TYPE; } else if (identifier instanceof APIProductIdentifier) { contentPath = APIUtil.getProductDocPath((APIProductIdentifier) identifier) + APIConstants.INLINE_DOCUMENT_CONTENT_DIR + RegistryConstants.PATH_SEPARATOR + documentationName; identifierType = APIConstants.API_PRODUCT_IDENTIFIER_TYPE; } String tenantDomain = getTenantDomain(identifier); Registry registry; boolean isTenantFlowStarted = false; try { if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { startTenantFlow(tenantDomain); isTenantFlowStarted = true; } /* If the API provider is a tenant, load tenant registry*/ if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { int id = getTenantManager().getTenantId(tenantDomain); registry = getRegistryService().getGovernanceSystemRegistry(id); } else { if (this.tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(this.tenantDomain)) { registry = getRegistryService().getGovernanceUserRegistry(identifier.getProviderName(), MultitenantConstants.SUPER_TENANT_ID); } else { registry = this.registry; } } if (registry.resourceExists(contentPath)) { Resource docContent = registry.get(contentPath); Object content = docContent.getContent(); if (content != null) { return new String((byte[]) docContent.getContent(), Charset.defaultCharset()); } } } catch (RegistryException e) { String msg = "No document content found for documentation: " + documentationName + " of " + identifierType + " : " + identifier.getName(); log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get document content found for documentation: " + documentationName + " of " + identifierType + " : " + identifier.getName(); log.error(msg, e); throw new APIManagementException(msg, e); } finally { if (isTenantFlowStarted) { endTenantFlow(); } } return null; } public Subscriber getSubscriberById(String accessToken) throws APIManagementException { return null; } public boolean isContextExist(String context) throws APIManagementException { // Since we don't have tenant in the APIM table, we do the filtering using this hack if (context != null && context.startsWith("/t/")) context = context.replace("/t/" + getTenantDomainFromUrl(context), ""); //removing prefix if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { context = "/t/" + tenantDomain + context; } return apiMgtDAO.isContextExist(context); } protected String getTenantDomainFromUrl(String url) { return MultitenantUtils.getTenantDomainFromUrl(url); } public boolean isScopeKeyExist(String scopeKey, int tenantid) throws APIManagementException { if (System.getProperty(APIConstants.ENABLE_DUPLICATE_SCOPES) != null && Boolean.parseBoolean(System.getProperty(APIConstants.ENABLE_DUPLICATE_SCOPES))) { return false; } return apiMgtDAO.isScopeKeyExist(scopeKey, tenantid); } public boolean isScopeKeyAssigned(APIIdentifier identifier, String scopeKey, int tenantid) throws APIManagementException { if (System.getProperty(APIConstants.ENABLE_DUPLICATE_SCOPES) != null && Boolean.parseBoolean(System.getProperty(APIConstants.ENABLE_DUPLICATE_SCOPES))) { return false; } return apiMgtDAO.isScopeKeyAssigned(identifier, scopeKey, tenantid); } public boolean isApiNameExist(String apiName) throws APIManagementException { String tenantName = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { tenantName = tenantDomain; } return apiMgtDAO.isApiNameExist(apiName, tenantName); } public boolean isApiNameWithDifferentCaseExist(String apiName) throws APIManagementException { String tenantName = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { tenantName = tenantDomain; } return apiMgtDAO.isApiNameWithDifferentCaseExist(apiName, tenantName); } public void addSubscriber(String username, String groupingId) throws APIManagementException { Subscriber subscriber = new Subscriber(username); subscriber.setSubscribedDate(new Date()); //TODO : need to set the proper email subscriber.setEmail(""); try { int tenantId = getTenantManager().getTenantId(getTenantDomain(username)); subscriber.setTenantId(tenantId); apiMgtDAO.addSubscriber(subscriber, groupingId); //Add a default application once subscriber is added addDefaultApplicationForSubscriber(subscriber); } catch (APIManagementException e) { String msg = "Error while adding the subscriber " + subscriber.getName(); log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Error while adding the subscriber " + subscriber.getName(); log.error(msg, e); throw new APIManagementException(msg, e); } } protected String getTenantDomain(String username) { return MultitenantUtils.getTenantDomain(username); } /** * Add default application on the first time a subscriber is added to the database * * @param subscriber Subscriber * @throws APIManagementException if an error occurs while adding default application */ private void addDefaultApplicationForSubscriber(Subscriber subscriber) throws APIManagementException { Application defaultApp = new Application(APIConstants.DEFAULT_APPLICATION_NAME, subscriber); if (APIUtil.isEnabledUnlimitedTier()) { defaultApp.setTier(APIConstants.UNLIMITED_TIER); } else { Map<String, Tier> throttlingTiers = APIUtil.getTiers(APIConstants.TIER_APPLICATION_TYPE, getTenantDomain(subscriber.getName())); Set<Tier> tierValueList = new HashSet<Tier>(throttlingTiers.values()); List<Tier> sortedTierList = APIUtil.sortTiers(tierValueList); defaultApp.setTier(sortedTierList.get(0).getName()); } //application will not be shared within the group defaultApp.setGroupId(""); defaultApp.setTokenType(APIConstants.DEFAULT_TOKEN_TYPE); apiMgtDAO.addApplication(defaultApp, subscriber.getName()); } public void updateSubscriber(Subscriber subscriber) throws APIManagementException { apiMgtDAO.updateSubscriber(subscriber); } public Subscriber getSubscriber(int subscriberId) throws APIManagementException { return apiMgtDAO.getSubscriber(subscriberId); } public ResourceFile getIcon(APIIdentifier identifier) throws APIManagementException { String artifactPath = APIConstants.API_IMAGE_LOCATION + RegistryConstants.PATH_SEPARATOR + identifier.getProviderName() + RegistryConstants.PATH_SEPARATOR + identifier.getApiName() + RegistryConstants.PATH_SEPARATOR + identifier.getVersion(); String tenantDomain = getTenantDomain(identifier); Registry registry; boolean isTenantFlowStarted = false; try { if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { startTenantFlow(tenantDomain); isTenantFlowStarted = true; } /* If the API provider is a tenant, load tenant registry*/ if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { int id = getTenantManager().getTenantId(tenantDomain); registry = getRegistryService().getGovernanceSystemRegistry(id); } else { if (this.tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(this.tenantDomain)) { registry = getRegistryService().getGovernanceUserRegistry(identifier.getProviderName(), MultitenantConstants.SUPER_TENANT_ID); } else { registry = this.registry; } } String thumbPath = artifactPath + RegistryConstants.PATH_SEPARATOR + APIConstants.API_ICON_IMAGE; if (registry.resourceExists(thumbPath)) { Resource res = registry.get(thumbPath); return new ResourceFile(res.getContentStream(), res.getMediaType()); } } catch (RegistryException e) { String msg = "Error while loading API icon of API " + identifier.getApiName() + ":" + identifier.getVersion() + " from the registry"; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Error while loading API icon of API " + identifier.getApiName() + ":" + identifier.getVersion(); log.error(msg, e); throw new APIManagementException(msg, e); } finally { if (isTenantFlowStarted) { endTenantFlow(); } } return null; } public Set<API> getSubscriberAPIs(Subscriber subscriber) throws APIManagementException { SortedSet<API> apiSortedSet = new TreeSet<API>(new APINameComparator()); Set<SubscribedAPI> subscribedAPIs = apiMgtDAO.getSubscribedAPIs(subscriber, null); for (SubscribedAPI subscribedApi : subscribedAPIs) { Application application = subscribedApi.getApplication(); if (application != null) { int applicationId = application.getId(); Set<APIKey> keys = getApplicationKeys(applicationId); for (APIKey key : keys) { application.addKey(key); } } } boolean isTenantFlowStarted = false; try { if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { isTenantFlowStarted = true; startTenantFlow(tenantDomain); } for (SubscribedAPI subscribedAPI : subscribedAPIs) { String apiPath = APIUtil.getAPIPath(subscribedAPI.getApiId()); Resource resource; try { resource = registry.get(apiPath); GenericArtifactManager artifactManager = getAPIGenericArtifactManager(registry, APIConstants.API_KEY); GenericArtifact artifact = artifactManager.getGenericArtifact(resource.getUUID()); API api = getAPI(artifact); if (api != null) { apiSortedSet.add(api); } } catch (RegistryException e) { String msg = "Failed to get APIs for subscriber: " + subscriber.getName(); log.error(msg, e); throw new APIManagementException(msg, e); } } } finally { if (isTenantFlowStarted) { endTenantFlow(); } } return apiSortedSet; } /** * To get the API from generic artifact, if the user is authorized to view it. * * @param apiArtifact API Artifact. * @return API if the user is authorized to view this. */ protected API getAPI(GenericArtifact apiArtifact) throws APIManagementException { return APIUtil.getAPI(apiArtifact, registry); } /** * Returns the corresponding application given the uuid. * * @param uuid uuid of the Application. * @return it will return Application corresponds to the uuid provided. * @throws APIManagementException */ public Application getApplicationByUUID(String uuid) throws APIManagementException { Application application = apiMgtDAO.getApplicationByUUID(uuid); if (application != null) { Set<APIKey> keys = getApplicationKeys(application.getId()); for (APIKey key : keys) { if (APIConstants.JWT.equals(application.getTokenType())) { key.setAccessToken(""); } application.addKey(key); } } return application; } @Override public Application getLightweightApplicationByUUID(String uuid) throws APIManagementException { return apiMgtDAO.getApplicationByUUID(uuid); } /** * returns the SubscribedAPI object which is related to the UUID * * @param uuid UUID of Subscription * @return SubscribedAPI object which is related to the UUID * @throws APIManagementException */ public SubscribedAPI getSubscriptionByUUID(String uuid) throws APIManagementException { return apiMgtDAO.getSubscriptionByUUID(uuid); } protected final void handleException(String msg, Exception e) throws APIManagementException { log.error(msg, e); throw new APIManagementException(msg, e); } protected final void handleException(String msg) throws APIManagementException { log.error(msg); throw new APIManagementException(msg); } protected final void handleResourceAlreadyExistsException(String msg) throws APIMgtResourceAlreadyExistsException { log.error(msg); throw new APIMgtResourceAlreadyExistsException(msg); } protected final void handleResourceNotFoundException(String msg) throws APIMgtResourceNotFoundException { log.error(msg); throw new APIMgtResourceNotFoundException(msg); } protected final void handlePolicyNotFoundException(String msg) throws PolicyNotFoundException { log.error(msg); throw new PolicyNotFoundException(msg); } protected final void handleBlockConditionNotFoundException(String msg) throws BlockConditionNotFoundException { log.error(msg); throw new BlockConditionNotFoundException(msg); } protected final void handleApplicationNameContainSpacesException(String msg) throws ApplicationNameWhiteSpaceValidationException { log.error(msg); throw new ApplicationNameWhiteSpaceValidationException(msg); } protected final void handleApplicationNameContainsInvalidCharactersException(String msg) throws ApplicationNameWithInvalidCharactersException { log.error(msg); throw new ApplicationNameWithInvalidCharactersException(msg); } public boolean isApplicationTokenExists(String accessToken) throws APIManagementException { return apiMgtDAO.isAccessTokenExists(accessToken); } public boolean isApplicationTokenRevoked(String accessToken) throws APIManagementException { return apiMgtDAO.isAccessTokenRevoked(accessToken); } public APIKey getAccessTokenData(String accessToken) throws APIManagementException { return apiMgtDAO.getAccessTokenData(accessToken); } public Map<Integer, APIKey> searchAccessToken(String searchType, String searchTerm, String loggedInUser) throws APIManagementException { return Collections.emptyMap(); } public Set<APIIdentifier> getAPIByAccessToken(String accessToken) throws APIManagementException { return Collections.emptySet(); } public API getAPI(APIIdentifier identifier, APIIdentifier oldIdentifier, String oldContext) throws APIManagementException { String apiPath = APIUtil.getAPIPath(identifier); try { GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_KEY); Resource apiResource = registry.get(apiPath); String artifactId = apiResource.getUUID(); if (artifactId == null) { throw new APIManagementException("artifact id is null for : " + apiPath); } GenericArtifact apiArtifact = artifactManager.getGenericArtifact(artifactId); return APIUtil.getAPI(apiArtifact, registry, oldIdentifier, oldContext); } catch (RegistryException e) { String msg = "Failed to get API from : " + apiPath; log.error(msg, e); throw new APIManagementException(msg, e); } } @Override public Set<Tier> getAllTiers() throws APIManagementException { Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator()); Map<String, Tier> tierMap; if (tenantId == MultitenantConstants.INVALID_TENANT_ID) { tierMap = APIUtil.getAllTiers(); } else { boolean isTenantFlowStarted = false; try { if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { startTenantFlow(tenantDomain); isTenantFlowStarted = true; } tierMap = APIUtil.getAllTiers(tenantId); } finally { if (isTenantFlowStarted) { endTenantFlow(); } } } tiers.addAll(tierMap.values()); return tiers; } @Override public Set<Tier> getAllTiers(String tenantDomain) throws APIManagementException { Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator()); Map<String, Tier> tierMap; boolean isTenantFlowStarted = false; try { if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { startTenantFlow(tenantDomain); isTenantFlowStarted = true; } int requestedTenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); if (requestedTenantId == MultitenantConstants.SUPER_TENANT_ID || requestedTenantId == MultitenantConstants.INVALID_TENANT_ID) { tierMap = APIUtil.getAllTiers(); } else { tierMap = APIUtil.getAllTiers(requestedTenantId); } } finally { if (isTenantFlowStarted) { endTenantFlow(); } } tiers.addAll(tierMap.values()); return tiers; } /** * Returns a list of pre-defined # {@link org.wso2.carbon.apimgt.api.model.Tier} in the system. * * @return Set<Tier> */ public Set<Tier> getTiers() throws APIManagementException { Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator()); Map<String, Tier> tierMap; if (!APIUtil.isAdvanceThrottlingEnabled()) { if (tenantId == MultitenantConstants.INVALID_TENANT_ID) { tierMap = APIUtil.getTiers(); } else { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId, true); tierMap = APIUtil.getTiers(tenantId); endTenantFlow(); } tiers.addAll(tierMap.values()); } else { tierMap = APIUtil.getTiersFromPolicies(PolicyConstants.POLICY_LEVEL_SUB, tenantId); tiers.addAll(tierMap.values()); } return tiers; } /** * Returns a list of pre-defined # {@link org.wso2.carbon.apimgt.api.model.Tier} in the system. * * @return Set<Tier> */ public Set<Tier> getTiers(String tenantDomain) throws APIManagementException { Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator()); Map<String, Tier> tierMap; if (!APIUtil.isAdvanceThrottlingEnabled()) { startTenantFlow(tenantDomain); int requestedTenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId(); if (requestedTenantId == MultitenantConstants.SUPER_TENANT_ID || requestedTenantId == MultitenantConstants.INVALID_TENANT_ID) { tierMap = APIUtil.getTiers(); } else { tierMap = APIUtil.getTiers(requestedTenantId); } tiers.addAll(tierMap.values()); endTenantFlow(); } else { tierMap = APIUtil.getTiersFromPolicies(PolicyConstants.POLICY_LEVEL_SUB, tenantId); tiers.addAll(tierMap.values()); } return tiers; } /** * Returns a list of pre-defined # {@link org.wso2.carbon.apimgt.api.model.Tier} in the system. * * @param tierType type of the tiers (api,resource ot application) * @param username current logged user * @return Set<Tier> return list of tier names * @throws APIManagementException APIManagementException if failed to get the predefined tiers */ public Set<Tier> getTiers(int tierType, String username) throws APIManagementException { Set<Tier> tiers = new TreeSet<Tier>(new TierNameComparator()); String tenantDomain = getTenantDomain(username); Map<String, Tier> tierMap; if (!APIUtil.isAdvanceThrottlingEnabled()) { tierMap = APIUtil.getTiers(tierType, tenantDomain); tiers.addAll(tierMap.values()); } else { int tenantIdFromUsername = APIUtil.getTenantId(username); if (tierType == APIConstants.TIER_API_TYPE) { tierMap = APIUtil.getTiersFromPolicies(PolicyConstants.POLICY_LEVEL_SUB, tenantIdFromUsername); } else if (tierType == APIConstants.TIER_RESOURCE_TYPE) { tierMap = APIUtil.getTiersFromPolicies(PolicyConstants.POLICY_LEVEL_API, tenantIdFromUsername); } else if (tierType == APIConstants.TIER_APPLICATION_TYPE) { tierMap = APIUtil.getTiersFromPolicies(PolicyConstants.POLICY_LEVEL_APP, tenantIdFromUsername); } else { throw new APIManagementException("No such a tier type : " + tierType); } tiers.addAll(tierMap.values()); } return tiers; } /** * Returns a list of pre-defined # {@link org.wso2.carbon.apimgt.api.model.Tier} in the system. * * @return Map<String, String> */ public Map<String, String> getTenantDomainMappings(String tenantDomain, String apiType) throws APIManagementException { return APIUtil.getDomainMappings(tenantDomain, apiType); } public boolean isDuplicateContextTemplate(String contextTemplate) throws APIManagementException { if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { if (contextTemplate != null && contextTemplate.startsWith("/t/")) { contextTemplate = contextTemplate.replace("/t/" + getTenantDomainFromUrl(contextTemplate), ""); } contextTemplate = "/t/" + tenantDomain + contextTemplate; } return apiMgtDAO.isDuplicateContextTemplate(contextTemplate); } @Override public List<String> getApiNamesMatchingContext(String contextTemplate) throws APIManagementException { return apiMgtDAO.getAPINamesMatchingContext(contextTemplate); } public Policy[] getPolicies(String username, String level) throws APIManagementException { Policy[] policies = null; int tenantID = APIUtil.getTenantId(username); if (PolicyConstants.POLICY_LEVEL_API.equals(level)) { policies = apiMgtDAO.getAPIPolicies(tenantID); } else if (PolicyConstants.POLICY_LEVEL_APP.equals(level)) { policies = apiMgtDAO.getApplicationPolicies(tenantID); } else if (PolicyConstants.POLICY_LEVEL_SUB.equals(level)) { policies = apiMgtDAO.getSubscriptionPolicies(tenantID); } else if (PolicyConstants.POLICY_LEVEL_GLOBAL.equals(level)) { policies = apiMgtDAO.getGlobalPolicies(tenantID); } //Get the API Manager configurations and check whether the unlimited tier is disabled. If disabled, remove // the tier from the array. APIManagerConfiguration apiManagerConfiguration = ServiceReferenceHolder.getInstance() .getAPIManagerConfigurationService().getAPIManagerConfiguration(); ThrottleProperties throttleProperties = apiManagerConfiguration.getThrottleProperties(); if (!throttleProperties.isEnableUnlimitedTier()) { List<Policy> policiesWithoutUnlimitedTier = new ArrayList<Policy>(); if (policies != null) { for (Policy policy : policies) { if (!APIConstants.UNLIMITED_TIER_NAME.equalsIgnoreCase(policy.getPolicyName())) { policiesWithoutUnlimitedTier.add(policy); } } } policies = policiesWithoutUnlimitedTier.toArray(new Policy[0]); } return policies; } @Override public Map<String, Object> searchPaginatedAPIs(String searchQuery, String requestedTenantDomain, int start, int end, boolean isLazyLoad) throws APIManagementException { Map<String, Object> result = new HashMap<String, Object>(); boolean isTenantFlowStarted = false; String[] searchQueries = searchQuery.split("&"); StringBuilder filteredQuery = new StringBuilder(); String subQuery = null; if (log.isDebugEnabled()) { log.debug("Original search query received : " + searchQuery); } // Filtering the queries related with custom properties for (String query : searchQueries) { if (searchQuery.startsWith(APIConstants.SUBCONTEXT_SEARCH_TYPE_PREFIX) || searchQuery.startsWith(APIConstants.DOCUMENTATION_SEARCH_TYPE_PREFIX)) { subQuery = query; break; } // If the query does not contains "=" then it is an errornous scenario. if (query.contains("=")) { String[] searchKeys = query.split("="); if (searchKeys.length >= 2) { //prevent api-meta. getting prefixed to labelName and restrict label serach to exact match only if (APIConstants.LABEL.equals(searchKeys[0])) { searchKeys[0] = APIConstants.API_LABELS_GATEWAY_LABELS; if (searchKeys[1].startsWith("*")) { searchKeys[1] = searchKeys[1].substring(1, searchKeys[1].length()); } if (searchKeys[1].endsWith("*")) { searchKeys[1] = searchKeys[1].substring(0, searchKeys[1].length() - 1); } } else if (!Arrays.asList(APIConstants.API_SEARCH_PREFIXES) .contains(searchKeys[0].toLowerCase())) { if (log.isDebugEnabled()) { log.debug(searchKeys[0] + " does not match with any of the reserved key words. Hence" + " appending " + APIConstants.API_RELATED_CUSTOM_PROPERTIES_PREFIX + " as prefix"); } searchKeys[0] = (APIConstants.API_RELATED_CUSTOM_PROPERTIES_PREFIX + searchKeys[0]); } if (filteredQuery.length() == 0) { filteredQuery.append(searchKeys[0]).append("=").append(searchKeys[1]); } else { filteredQuery.append("&").append(searchKeys[0]).append("=").append(searchKeys[1]); } } } else { filteredQuery.append(query); } } searchQuery = filteredQuery.toString(); if (log.isDebugEnabled()) { log.debug("Final search query after the post processing for the custom properties : " + searchQuery); } try { boolean isTenantMode = (requestedTenantDomain != null); if (isTenantMode && !org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME .equals(requestedTenantDomain)) { isTenantFlowStarted = true; startTenantFlow(requestedTenantDomain); } else { requestedTenantDomain = org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; isTenantFlowStarted = true; startTenantFlow(requestedTenantDomain); } Registry userRegistry; int tenantIDLocal = 0; String userNameLocal = this.username; if ((isTenantMode && this.tenantDomain == null) || (isTenantMode && isTenantDomainNotMatching(requestedTenantDomain))) {//Tenant store anonymous mode tenantIDLocal = getTenantManager().getTenantId(requestedTenantDomain); userRegistry = getRegistryService() .getGovernanceUserRegistry(CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME, tenantIDLocal); userNameLocal = CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME; } else { userRegistry = this.registry; tenantIDLocal = tenantId; } PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(userNameLocal); if (subQuery != null && subQuery.startsWith(APIConstants.DOCUMENTATION_SEARCH_TYPE_PREFIX)) { Map<Documentation, API> apiDocMap = searchAPIDoc(userRegistry, tenantIDLocal, userNameLocal, subQuery.split("=")[1]); result.put("apis", apiDocMap); /*Pagination for Document search results is not supported yet, hence length is sent as end-start*/ if (apiDocMap.isEmpty()) { result.put("length", 0); } else { result.put("length", end - start); } } else if (subQuery != null && subQuery.startsWith(APIConstants.SUBCONTEXT_SEARCH_TYPE_PREFIX)) { result = searchAPIsByURLPattern(userRegistry, subQuery.split("=")[1], start, end); } else if (searchQuery != null && searchQuery.startsWith(APIConstants.CONTENT_SEARCH_TYPE_PREFIX)) { result = searchPaginatedAPIsByContent(userRegistry, tenantIDLocal, searchQuery, start, end, isLazyLoad); } else { result = searchPaginatedAPIs(userRegistry, searchQuery, start, end, isLazyLoad); } } catch (Exception e) { String msg = "Failed to Search APIs"; log.error(msg, e); throw new APIManagementException(msg, e); } finally { if (isTenantFlowStarted) { endTenantFlow(); } } return result; } /** * To search API With URL pattern * @param registry Registry to search. * @param searchTerm Term to be searched. * @param start Start index * @param end End index. * @return All the APIs, that matches given criteria * @throws APIManagementException API Management Exception. */ protected Map<String, Object> searchAPIsByURLPattern(Registry registry, String searchTerm, int start, int end) throws APIManagementException { return APIUtil.searchAPIsByURLPattern(registry, searchTerm, start, end); } /** * Delete an existing global mediation policy * * @param mediationPolicyId uuid of the global mediation policy * @return true if deleted successfully * @throws APIManagementException If failed to delete mediation policy */ @Override public boolean deleteGlobalMediationPolicy(String mediationPolicyId) throws APIManagementException { //Get registry resource correspond to the uuid Resource mediationResource = this.getCustomMediationResourceFromUuid(mediationPolicyId); if (mediationResource != null) { //If resource exists String mediationPath = mediationResource.getPath(); try { if (registry.resourceExists(mediationPath)) { ////TODO : validation if policy been use by any API registry.delete(mediationPath); //Verify if deleted successfully if (!registry.resourceExists(mediationPath)) { if (log.isDebugEnabled()) { log.debug("Mediation policy deleted successfully"); } return true; } } } catch (RegistryException e) { String msg = "Failed to delete global mediation policy " + mediationPolicyId; log.error(msg, e); throw new APIManagementException(msg, e); } } return false; } /** * Returns the uuid of the updated/created mediation policy * * @param mediationPolicyPath path to the registry resource * @return uuid of the given registry resource or null */ @Override public String getCreatedResourceUuid(String mediationPolicyPath) { try { Resource resource = registry.get(mediationPolicyPath); return resource.getUUID(); } catch (RegistryException e) { log.error("error occurred while getting created mediation policy uuid", e); } return null; } /** * Returns the mediation policy registry resource correspond to the given identifier * * @param mediationPolicyId uuid of the mediation resource * @return Registry resource of given identifier or null * @throws APIManagementException If failed to get the registry resource of given uuid */ @Override public Resource getCustomMediationResourceFromUuid(String mediationPolicyId) throws APIManagementException { String resourcePath = APIConstants.API_CUSTOM_SEQUENCE_LOCATION; try { Resource resource = registry.get(resourcePath); //resource : customsequences if (resource instanceof Collection) { Collection typeCollection = (Collection) resource; String[] typeArray = typeCollection.getChildren(); for (String type : typeArray) { Resource typeResource = registry.get(type); //typeResource: in/ out/ fault if (typeResource instanceof Collection) { String[] policyArray = ((Collection) typeResource).getChildren(); if (policyArray.length > 0) { for (String policy : policyArray) { Resource mediationResource = registry.get(policy); //mediationResource: eg .log_in_msg.xml String resourceId = mediationResource.getUUID(); if (resourceId.equals(mediationPolicyId)) { //If registry resource id matches given identifier returns that // registry resource return mediationResource; } } } } } } } catch (RegistryException e) { String msg = "Error while accessing registry objects"; log.error(msg, e); throw new APIManagementException(msg, e); } return null; } /** * Returns Registry resource matching given mediation policy identifier * * @param uuid mediation policy identifier * @param resourcePath registry path to the API resource * @return Registry resource matches given identifier or null * @throws APIManagementException If fails to get the resource matching given identifier */ @Override public Resource getApiSpecificMediationResourceFromUuid(String uuid, String resourcePath) throws APIManagementException { try { Resource resource = registry.get(resourcePath); if (resource instanceof Collection) { Collection typeCollection = (Collection) resource; String[] typeArray = typeCollection.getChildren(); for (String type : typeArray) { //Check for mediation policy resource if ((type.equalsIgnoreCase(resourcePath + RegistryConstants.PATH_SEPARATOR + APIConstants.API_CUSTOM_SEQUENCE_TYPE_IN)) || (type.equalsIgnoreCase(resourcePath + RegistryConstants.PATH_SEPARATOR + APIConstants.API_CUSTOM_SEQUENCE_TYPE_OUT)) || (type.equalsIgnoreCase(resourcePath + RegistryConstants.PATH_SEPARATOR + APIConstants.API_CUSTOM_SEQUENCE_TYPE_FAULT))) { Resource sequenceType = registry.get(type); //sequenceType eg: in / out /fault if (sequenceType instanceof Collection) { String[] mediationPolicyArr = ((Collection) sequenceType).getChildren(); for (String mediationPolicy : mediationPolicyArr) { Resource mediationResource = registry.get(mediationPolicy); String resourceId = mediationResource.getUUID(); if (resourceId.equalsIgnoreCase(uuid)) { return mediationResource; } } } } } } } catch (RegistryException e) { String msg = "Error while obtaining registry objects"; log.error(msg, e); throw new APIManagementException(msg, e); } return null; } /** * Returns a list of API specific mediation policies from registry * * @param apiIdentifier API identifier * @return List of api specific mediation objects available * @throws APIManagementException If unable to get mediation policies of specified API Id */ @Override public List<Mediation> getAllApiSpecificMediationPolicies(APIIdentifier apiIdentifier) throws APIManagementException { List<Mediation> mediationList = new ArrayList<Mediation>(); Mediation mediation; String apiResourcePath = APIUtil.getAPIPath(apiIdentifier); apiResourcePath = apiResourcePath.substring(0, apiResourcePath.lastIndexOf("/")); try { //Getting API registry resource Resource resource = registry.get(apiResourcePath); //resource eg: /_system/governance/apimgt/applicationdata/provider/admin/calculatorAPI/2.0 if (resource instanceof Collection) { Collection typeCollection = (Collection) resource; String[] typeArray = typeCollection.getChildren(); for (String type : typeArray) { //Check for mediation policy sequences if ((type.equalsIgnoreCase(apiResourcePath + RegistryConstants.PATH_SEPARATOR + APIConstants.API_CUSTOM_SEQUENCE_TYPE_IN)) || (type.equalsIgnoreCase(apiResourcePath + RegistryConstants.PATH_SEPARATOR + APIConstants.API_CUSTOM_SEQUENCE_TYPE_OUT)) || (type.equalsIgnoreCase(apiResourcePath + RegistryConstants.PATH_SEPARATOR + APIConstants.API_CUSTOM_SEQUENCE_TYPE_FAULT))) { Resource typeResource = registry.get(type); //typeResource : in / out / fault if (typeResource instanceof Collection) { String[] mediationPolicyArr = ((Collection) typeResource).getChildren(); if (mediationPolicyArr.length > 0) { for (String mediationPolicy : mediationPolicyArr) { Resource policyResource = registry.get(mediationPolicy); //policyResource eg: custom_in_message //Get uuid of the registry resource String resourceId = policyResource.getUUID(); //Get mediation policy config try { String contentString = IOUtils.toString(policyResource.getContentStream(), RegistryConstants.DEFAULT_CHARSET_ENCODING); //Extract name from the policy config OMElement omElement = AXIOMUtil.stringToOM(contentString); OMAttribute attribute = omElement.getAttribute(new QName("name")); String mediationPolicyName = attribute.getAttributeValue(); mediation = new Mediation(); mediation.setUuid(resourceId); mediation.setName(mediationPolicyName); //Extracting mediation policy type from the registry resource path String resourceType = type.substring(type.lastIndexOf("/") + 1); mediation.setType(resourceType); mediationList.add(mediation); } catch (XMLStreamException e) { // If exception been caught flow will continue with next mediation policy log.error("Error occurred while getting omElement out of" + " mediation content", e); } catch (IOException e) { log.error( "Error occurred while converting the content " + "stream of mediation " + mediationPolicy + " to string", e); } } } } } } } } catch (RegistryException e) { String msg = "Error occurred while getting Api Specific mediation policies "; log.error(msg, e); throw new APIManagementException(msg, e); } return mediationList; } /** * Returns the mediation policy name specify inside mediation config * * @param config mediation config content * @return name of the mediation policy or null */ @Override public String getMediationNameFromConfig(String config) { try { //convert xml content in to json String configInJson = XML.toJSONObject(config).toString(); JSONParser parser = new JSONParser(); //Extracting mediation policy name from the json string JSONObject jsonObject = (JSONObject) parser.parse(configInJson); JSONObject rootObject = (JSONObject) jsonObject.get(APIConstants.MEDIATION_SEQUENCE_ELEM); String name = rootObject.get(APIConstants.POLICY_NAME_ELEM).toString(); //explicitly add .xml extension to the name and return return name + APIConstants.MEDIATION_CONFIG_EXT; } catch (JSONException e) { log.error("Error occurred while converting the mediation config string to json", e); } catch (ParseException e) { log.error("Error occurred while parsing config json string in to json object", e); } return null; } /** * Returns Mediation policy specify by given identifier * * @param apiResourcePath registry path to the API resource * @param mediationPolicyId mediation policy identifier * @return Mediation object contains details of the mediation policy or null */ @Override public Mediation getApiSpecificMediationPolicy(String apiResourcePath, String mediationPolicyId) throws APIManagementException { //Get registry resource correspond to given policy identifier Resource mediationResource = getApiSpecificMediationResourceFromUuid(mediationPolicyId, apiResourcePath); Mediation mediation = null; if (mediationResource != null) { try { //Get mediation policy config content String contentString = IOUtils.toString(mediationResource.getContentStream(), RegistryConstants.DEFAULT_CHARSET_ENCODING); //Extracting name specified in the mediation config OMElement omElement = AXIOMUtil.stringToOM(contentString); OMAttribute attribute = omElement.getAttribute(new QName("name")); String mediationPolicyName = attribute.getAttributeValue(); mediation = new Mediation(); mediation.setUuid(mediationResource.getUUID()); mediation.setName(mediationPolicyName); //Extracting mediation policy type from registry path String resourcePath = mediationResource.getPath(); String[] path = resourcePath.split(RegistryConstants.PATH_SEPARATOR); String resourceType = path[(path.length - 2)]; mediation.setType(resourceType); mediation.setConfig(contentString); } catch (XMLStreamException e) { String errorMsg = "Error occurred while getting omElement out of mediation content"; log.error(errorMsg, e); throw new APIManagementException(errorMsg, e); } catch (IOException e) { String errorMsg = "Error occurred while converting content stream into string "; log.error(errorMsg, e); throw new APIManagementException(errorMsg, e); } catch (RegistryException e) { String errorMsg = "Error occurred while accessing content stream of mediation" + " policy"; log.error(errorMsg, e); throw new APIManagementException(errorMsg, e); } } return mediation; } /** * Delete existing API specific mediation policy * * @param apiResourcePath path to the API registry resource * @param mediationPolicyId mediation policy identifier */ @Override public Boolean deleteApiSpecificMediationPolicy(String apiResourcePath, String mediationPolicyId) throws APIManagementException { Resource mediationResource = this.getApiSpecificMediationResourceFromUuid(mediationPolicyId, apiResourcePath); if (mediationResource != null) { //If resource exists String mediationPath = mediationResource.getPath(); try { if (registry.resourceExists(mediationPath)) { registry.delete(mediationPath); if (!registry.resourceExists(mediationPath)) { if (log.isDebugEnabled()) { log.debug("Mediation policy deleted successfully"); } return true; } } } catch (RegistryException e) { String msg = "Failed to delete specific mediation policy "; log.error(msg, e); throw new APIManagementException(msg, e); } } return false; } /** * Returns true if resource already exists in registry * * @param mediationPolicyPath resource path * @return true, If resource exists */ @Override public boolean checkIfResourceExists(String mediationPolicyPath) throws APIManagementException { boolean value = false; try { if (registry.resourceExists(mediationPolicyPath)) { value = true; } } catch (RegistryException e) { String msg = "Error while obtaining registry objects"; log.error(msg, e); throw new APIManagementException(msg, e); } return value; } @Override public List<String> getApiVersionsMatchingApiName(String apiName, String username) throws APIManagementException { return apiMgtDAO.getAPIVersionsMatchingApiName(apiName, username); } /** * Returns API Search result based on the provided query. This search method supports '&' based concatenate * search in multiple fields. * * @param registry * @param searchQuery Ex: provider=*admin*&version=*1* * @return API result * @throws APIManagementException */ public Map<String, Object> searchPaginatedAPIs(Registry registry, String searchQuery, int start, int end, boolean limitAttributes) throws APIManagementException { SortedSet<API> apiSet = new TreeSet<API>(new APINameComparator()); List<API> apiList = new ArrayList<API>(); Map<String, Object> result = new HashMap<String, Object>(); int totalLength = 0; boolean isMore = false; try { String paginationLimit = getAPIManagerConfiguration() .getFirstProperty(APIConstants.API_STORE_APIS_PER_PAGE); // If the Config exists use it to set the pagination limit final int maxPaginationLimit; if (paginationLimit != null) { // The additional 1 added to the maxPaginationLimit is to help us determine if more // APIs may exist so that we know that we are unable to determine the actual total // API count. We will subtract this 1 later on so that it does not interfere with // the logic of the rest of the application int pagination = Integer.parseInt(paginationLimit); // Because the store jaggery pagination logic is 10 results per a page we need to set pagination // limit to at least 11 or the pagination done at this level will conflict with the store pagination // leading to some of the APIs not being displayed if (pagination < 11) { pagination = 11; log.warn( "Value of '" + APIConstants.API_STORE_APIS_PER_PAGE + "' is too low, defaulting to 11"); } maxPaginationLimit = start + pagination + 1; } // Else if the config is not specified we go with default functionality and load all else { maxPaginationLimit = Integer.MAX_VALUE; } PaginationContext.init(start, end, "ASC", APIConstants.API_OVERVIEW_NAME, maxPaginationLimit); List<GovernanceArtifact> governanceArtifacts = GovernanceUtils.findGovernanceArtifacts( getSearchQuery(searchQuery), registry, APIConstants.API_RXT_MEDIA_TYPE, true); totalLength = PaginationContext.getInstance().getLength(); boolean isFound = true; if (governanceArtifacts == null || governanceArtifacts.size() == 0) { if (searchQuery.contains(APIConstants.API_OVERVIEW_PROVIDER)) { searchQuery = searchQuery.replaceAll(APIConstants.API_OVERVIEW_PROVIDER, APIConstants.API_OVERVIEW_OWNER); governanceArtifacts = GovernanceUtils.findGovernanceArtifacts(getSearchQuery(searchQuery), registry, APIConstants.API_RXT_MEDIA_TYPE, true); if (governanceArtifacts == null || governanceArtifacts.size() == 0) { isFound = false; } } else { isFound = false; } } if (!isFound) { result.put("apis", apiSet); result.put("length", 0); result.put("isMore", isMore); return result; } // Check to see if we can speculate that there are more APIs to be loaded if (maxPaginationLimit == totalLength) { isMore = true; // More APIs exist, cannot determine total API count without incurring perf hit --totalLength; // Remove the additional 1 added earlier when setting max pagination limit } int tempLength = 0; for (GovernanceArtifact artifact : governanceArtifacts) { API resultAPI; if (limitAttributes) { resultAPI = APIUtil.getAPI(artifact); } else { resultAPI = APIUtil.getAPI(artifact, registry); } if (resultAPI != null) { apiList.add(resultAPI); } // Ensure the APIs returned matches the length, there could be an additional API // returned due incrementing the pagination limit when getting from registry tempLength++; if (tempLength >= totalLength) { break; } } // Creating a apiIds string String apiIdsString = ""; int apiCount = apiList.size(); for (int i = 0; i < apiCount; i++) { String apiId = apiList.get(i).getId().getApplicationId(); if (apiId != null && apiId != "") { if (apiIdsString == "") { apiIdsString = apiId; } else { apiIdsString = apiIdsString + "," + apiId; } } } // setting scope if (apiIdsString != "") { KeyManager keyManager = KeyManagerHolder.getKeyManagerInstance(); Map<String, Set<Scope>> apiScopeSet = keyManager.getScopesForAPIS(apiIdsString); if (apiScopeSet.size() > 0) { for (int i = 0; i < apiCount; i++) { String apiId = apiList.get(i).getId().getApplicationId(); if (apiId != null && apiId != "") { Set<Scope> scopes = apiScopeSet.get(apiId); apiList.get(i).setScopes(scopes); } } } } apiSet.addAll(apiList); } catch (RegistryException e) { String msg = "Failed to search APIs with type"; log.error(msg, e); throw new APIManagementException(msg, e); } finally { PaginationContext.destroy(); } result.put("apis", apiSet); result.put("length", totalLength); result.put("isMore", isMore); return result; } /** * Search api resources by their content * * @param registry * @param searchQuery * @param start * @param end * @return * @throws APIManagementException */ public Map<String, Object> searchPaginatedAPIsByContent(Registry registry, int tenantId, String searchQuery, int start, int end, boolean limitAttributes) throws APIManagementException { SortedSet<API> apiSet = new TreeSet<API>(new APINameComparator()); Map<Documentation, API> docMap = new HashMap<Documentation, API>(); Map<String, Object> result = new HashMap<String, Object>(); int totalLength = 0; boolean isMore = false; //SortedSet<Object> compoundResult = new TreeSet<Object>(new ContentSearchResultNameComparator()); ArrayList<Object> compoundResult = new ArrayList<Object>(); try { GenericArtifactManager apiArtifactManager = APIUtil.getArtifactManager(registry, APIConstants.API_KEY); GenericArtifactManager docArtifactManager = APIUtil.getArtifactManager(registry, APIConstants.DOCUMENTATION_KEY); String paginationLimit = getAPIManagerConfiguration() .getFirstProperty(APIConstants.API_STORE_APIS_PER_PAGE); // If the Config exists use it to set the pagination limit final int maxPaginationLimit; if (paginationLimit != null) { // The additional 1 added to the maxPaginationLimit is to help us determine if more // APIs may exist so that we know that we are unable to determine the actual total // API count. We will subtract this 1 later on so that it does not interfere with // the logic of the rest of the application int pagination = Integer.parseInt(paginationLimit); // Because the store jaggery pagination logic is 10 results per a page we need to set pagination // limit to at least 11 or the pagination done at this level will conflict with the store pagination // leading to some of the APIs not being displayed if (pagination < 11) { pagination = 11; log.warn( "Value of '" + APIConstants.API_STORE_APIS_PER_PAGE + "' is too low, defaulting to 11"); } maxPaginationLimit = start + pagination + 1; } // Else if the config is not specified we go with default functionality and load all else { maxPaginationLimit = Integer.MAX_VALUE; } PaginationContext.init(start, end, "ASC", APIConstants.API_OVERVIEW_NAME, maxPaginationLimit); if (tenantId == -1) { tenantId = MultitenantConstants.SUPER_TENANT_ID; } UserRegistry systemUserRegistry = ServiceReferenceHolder.getInstance().getRegistryService() .getRegistry(CarbonConstants.REGISTRY_SYSTEM_USERNAME, tenantId); ContentBasedSearchService contentBasedSearchService = new ContentBasedSearchService(); String newSearchQuery = getSearchQuery(searchQuery); String[] searchQueries = newSearchQuery.split("&"); String apiState = ""; String publisherRoles = ""; Map<String, String> attributes = new HashMap<String, String>(); for (String searchCriterea : searchQueries) { String[] keyVal = searchCriterea.split("="); if (APIConstants.STORE_VIEW_ROLES.equals(keyVal[0])) { attributes.put("propertyName", keyVal[0]); attributes.put("rightPropertyValue", keyVal[1]); attributes.put("rightOp", "eq"); } else if (APIConstants.PUBLISHER_ROLES.equals(keyVal[0])) { publisherRoles = keyVal[1]; } else { if (APIConstants.LCSTATE_SEARCH_KEY.equals(keyVal[0])) { apiState = keyVal[1]; continue; } attributes.put(keyVal[0], keyVal[1]); } } //check whether the new document indexer is engaged RegistryConfigLoader registryConfig = RegistryConfigLoader.getInstance(); Map<String, Indexer> indexerMap = registryConfig.getIndexerMap(); Indexer documentIndexer = indexerMap.get(APIConstants.DOCUMENT_MEDIA_TYPE_KEY); String complexAttribute; if (documentIndexer != null && documentIndexer instanceof DocumentIndexer) { //field check on document_indexed was added to prevent unindexed(by new DocumentIndexer) from coming up as search results //on indexed documents this property is always set to true complexAttribute = ClientUtils.escapeQueryChars(APIConstants.API_RXT_MEDIA_TYPE) + " OR mediaType_s:(" + ClientUtils.escapeQueryChars(APIConstants.DOCUMENT_RXT_MEDIA_TYPE) + " AND document_indexed_s:true)"; //construct query such that publisher roles is checked in properties for api artifacts and in fields for document artifacts //this was designed this way so that content search can be fully functional if registry is re-indexed after engaging DocumentIndexer if (!StringUtils.isEmpty(publisherRoles)) { complexAttribute = "(" + ClientUtils.escapeQueryChars(APIConstants.API_RXT_MEDIA_TYPE) + " AND publisher_roles_ss:" + publisherRoles + ") OR mediaType_s:(" + ClientUtils.escapeQueryChars(APIConstants.DOCUMENT_RXT_MEDIA_TYPE) + " AND publisher_roles_s:" + publisherRoles + ")"; } } else { //document indexer required for document content search is not engaged, therefore carry out the search only for api artifact contents complexAttribute = ClientUtils.escapeQueryChars(APIConstants.API_RXT_MEDIA_TYPE); if (!StringUtils.isEmpty(publisherRoles)) { complexAttribute = "(" + ClientUtils.escapeQueryChars(APIConstants.API_RXT_MEDIA_TYPE) + " AND publisher_roles_ss:" + publisherRoles + ")"; } } attributes.put(APIConstants.DOCUMENTATION_SEARCH_MEDIA_TYPE_FIELD, complexAttribute); attributes.put(APIConstants.API_OVERVIEW_STATUS, apiState); SearchResultsBean resultsBean = contentBasedSearchService.searchByAttribute(attributes, systemUserRegistry); String errorMsg = resultsBean.getErrorMessage(); if (errorMsg != null) { handleException(errorMsg); } ResourceData[] resourceData = resultsBean.getResourceDataList(); if (resourceData == null || resourceData.length == 0) { result.put("apis", compoundResult); result.put("length", 0); result.put("isMore", isMore); } totalLength = PaginationContext.getInstance().getLength(); // Check to see if we can speculate that there are more APIs to be loaded if (maxPaginationLimit == totalLength) { isMore = true; // More APIs exist, cannot determine total API count without incurring perf hit --totalLength; // Remove the additional 1 added earlier when setting max pagination limit } for (ResourceData data : resourceData) { String resourcePath = data.getResourcePath(); int index = resourcePath.indexOf(APIConstants.APIMGT_REGISTRY_LOCATION); resourcePath = resourcePath.substring(index); Resource resource = registry.get(resourcePath); if (APIConstants.DOCUMENT_RXT_MEDIA_TYPE.equals(resource.getMediaType())) { Resource docResource = registry.get(resourcePath); String docArtifactId = docResource.getUUID(); GenericArtifact docArtifact = docArtifactManager.getGenericArtifact(docArtifactId); Documentation doc = APIUtil.getDocumentation(docArtifact); Association[] docAssociations = registry.getAssociations(resourcePath, APIConstants.DOCUMENTATION_ASSOCIATION); API associatedAPI = null; if (docAssociations.length > 0) { // a content can have one api association at most String apiPath = docAssociations[0].getSourcePath(); Resource apiResource = registry.get(apiPath); String apiArtifactId = apiResource.getUUID(); if (apiArtifactId != null) { GenericArtifact apiArtifact = apiArtifactManager.getGenericArtifact(apiArtifactId); associatedAPI = APIUtil.getAPI(apiArtifact, registry); } else { throw new GovernanceException("artifact id is null for " + apiPath); } if (associatedAPI != null && doc != null) { docMap.put(doc, associatedAPI); } } } else { String apiArtifactId = resource.getUUID(); API api; if (apiArtifactId != null) { GenericArtifact apiArtifact = apiArtifactManager.getGenericArtifact(apiArtifactId); api = APIUtil.getAPI(apiArtifact, registry); apiSet.add(api); } else { throw new GovernanceException("artifact id is null for " + resourcePath); } } } compoundResult.addAll(apiSet); compoundResult.addAll(docMap.entrySet()); compoundResult.sort(new ContentSearchResultNameComparator()); } catch (RegistryException e) { handleException("Failed to search APIs by content", e); } catch (IndexerException e) { handleException("Failed to search APIs by content", e); } result.put("apis", compoundResult); result.put("length", totalLength); result.put("isMore", isMore); return result; } /** * gets the swagger definition timestamps as a map * * @param apiIdentifier * @return * @throws APIManagementException */ public Map<String, String> getSwaggerDefinitionTimeStamps(APIIdentifier apiIdentifier) throws APIManagementException { String apiTenantDomain = getTenantDomain(apiIdentifier); try { Registry registryType; //Tenant store anonymous mode if current tenant and the required tenant is not matching if (this.tenantDomain == null || isTenantDomainNotMatching(apiTenantDomain)) { int tenantId = getTenantManager().getTenantId(apiTenantDomain); registryType = getRegistryService() .getGovernanceUserRegistry(CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME, tenantId); } else { registryType = registry; } return OASParserUtil.getAPIOpenAPIDefinitionTimeStamps(apiIdentifier, registryType); } catch (org.wso2.carbon.user.api.UserStoreException e) { log.error("Error while getting the lastUpdated time due to " + e.getMessage(), e); } catch (RegistryException e) { log.debug("Error while getting the lastUpdated time due to " + e.getMessage(), e); } return null; } protected RegistryService getRegistryService() { return ServiceReferenceHolder.getInstance().getRegistryService(); } /** * get the thumbnailLastUpdatedTime for a thumbnail for a given api * * @param apiIdentifier * @return * @throws APIManagementException */ @Override public String getThumbnailLastUpdatedTime(APIIdentifier apiIdentifier) throws APIManagementException { String artifactPath = APIConstants.API_IMAGE_LOCATION + RegistryConstants.PATH_SEPARATOR + apiIdentifier.getProviderName() + RegistryConstants.PATH_SEPARATOR + apiIdentifier.getApiName() + RegistryConstants.PATH_SEPARATOR + apiIdentifier.getVersion(); String thumbPath = artifactPath + RegistryConstants.PATH_SEPARATOR + APIConstants.API_ICON_IMAGE; try { if (registry.resourceExists(thumbPath)) { Resource res = registry.get(thumbPath); Date lastModifiedTime = res.getLastModified(); return lastModifiedTime == null ? String.valueOf(res.getCreatedTime().getTime()) : String.valueOf(lastModifiedTime.getTime()); } } catch (RegistryException e) { String msg = "Error while loading API icon from the registry"; log.error(msg, e); throw new APIManagementException(msg, e); } return null; } /** * Search Apis by Doc Content * * @param registry - Registry which is searched * @param tenantID - Tenant id of logged in domain * @param username - Logged in username * @param searchTerm - Search value for doc * @return - Documentation to APIs map * @throws APIManagementException - If failed to get ArtifactManager for given tenant */ public Map<Documentation, API> searchAPIDoc(Registry registry, int tenantID, String username, String searchTerm) throws APIManagementException { return APIUtil.searchAPIsByDoc(registry, tenantID, username, searchTerm, APIConstants.STORE_CLIENT); } /** * Returns API manager configurations. * * @return APIManagerConfiguration object */ protected APIManagerConfiguration getAPIManagerConfiguration() { return ServiceReferenceHolder.getInstance().getAPIManagerConfigurationService() .getAPIManagerConfiguration(); } /** * To get the search query. * * @param searchQuery Initial query */ protected String getSearchQuery(String searchQuery) throws APIManagementException { return searchQuery; } /** * Returns all API keys associated with given application id. * * @param applicationId The id of the application. * @return Set<APIKey> Set of API keys of the application. * @throws APIManagementException */ private Set<APIKey> getApplicationKeys(int applicationId) throws APIManagementException { Set<APIKey> apiKeys = new HashSet<APIKey>(); APIKey productionKey = getApplicationKey(applicationId, APIConstants.API_KEY_TYPE_PRODUCTION); if (productionKey != null) { apiKeys.add(productionKey); } else { productionKey = apiMgtDAO.getKeyStatusOfApplication(APIConstants.API_KEY_TYPE_PRODUCTION, applicationId); if (productionKey != null) { productionKey.setType(APIConstants.API_KEY_TYPE_PRODUCTION); apiKeys.add(productionKey); } } APIKey sandboxKey = getApplicationKey(applicationId, APIConstants.API_KEY_TYPE_SANDBOX); if (sandboxKey != null) { apiKeys.add(sandboxKey); } else { sandboxKey = apiMgtDAO.getKeyStatusOfApplication(APIConstants.API_KEY_TYPE_SANDBOX, applicationId); if (sandboxKey != null) { sandboxKey.setType(APIConstants.API_KEY_TYPE_SANDBOX); apiKeys.add(sandboxKey); } } return apiKeys; } /** * Returns the key associated with given application id and key type. * * @param applicationId Id of the Application. * @param keyType The type of key. * @return APIKey The key of the application. * @throws APIManagementException */ private APIKey getApplicationKey(int applicationId, String keyType) throws APIManagementException { String consumerKey = apiMgtDAO.getConsumerkeyByApplicationIdAndKeyType(String.valueOf(applicationId), keyType); if (StringUtils.isNotEmpty(consumerKey)) { String consumerKeyStatus = apiMgtDAO.getKeyStatusOfApplication(keyType, applicationId).getState(); KeyManager keyManager = KeyManagerHolder.getKeyManagerInstance(); OAuthApplicationInfo oAuthApplicationInfo = keyManager.retrieveApplication(consumerKey); AccessTokenInfo tokenInfo = keyManager.getAccessTokenByConsumerKey(consumerKey); APIKey apiKey = new APIKey(); apiKey.setConsumerKey(consumerKey); apiKey.setType(keyType); apiKey.setState(consumerKeyStatus); if (oAuthApplicationInfo != null) { apiKey.setConsumerSecret(oAuthApplicationInfo.getClientSecret()); apiKey.setCallbackUrl(oAuthApplicationInfo.getCallBackURL()); apiKey.setGrantTypes(oAuthApplicationInfo.getParameter(APIConstants.JSON_GRANT_TYPES).toString()); } if (tokenInfo != null) { apiKey.setAccessToken(tokenInfo.getAccessToken()); apiKey.setValidityPeriod(tokenInfo.getValidityPeriod()); apiKey.setTokenScope(getScopeString(tokenInfo.getScopes())); } else { if (log.isDebugEnabled()) { log.debug("Access token does not exist for Consumer Key: " + consumerKey); } } return apiKey; } if (log.isDebugEnabled()) { log.debug("Consumer key does not exist for Application Id: " + applicationId + " Key Type: " + keyType); } return null; } /** * Returns a single string containing the provided array of scopes. * * @param scopes The array of scopes. * @return String Single string containing the provided array of scopes. */ private String getScopeString(String[] scopes) { return StringUtils.join(scopes, " "); } /** * Returns the corresponding application given the subscriberId and application name. * * @param subscriberId subscriberId of the Application * @param applicationName name of the Application * @throws APIManagementException */ public Application getApplicationBySubscriberIdAndName(int subscriberId, String applicationName) throws APIManagementException { Application application = apiMgtDAO.getApplicationBySubscriberIdAndName(subscriberId, applicationName); if (application != null) { Set<APIKey> keys = getApplicationKeys(application.getId()); for (APIKey key : keys) { if (APIConstants.JWT.equals(application.getTokenType())) { key.setAccessToken(""); } application.addKey(key); } } return application; } /** * Get API Product by registry artifact id * * @param uuid Registry artifact id * @param requestedTenantDomain tenantDomain for the registry * @return API Product of the provided artifact id * @throws APIManagementException */ public APIProduct getAPIProductbyUUID(String uuid, String requestedTenantDomain) throws APIManagementException { try { Registry registry; if (requestedTenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(requestedTenantDomain)) { int id = getTenantManager().getTenantId(requestedTenantDomain); registry = getRegistryService().getGovernanceSystemRegistry(id); } else { if (this.tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(this.tenantDomain)) { // at this point, requested tenant = carbon.super but logged in user is anonymous or tenant registry = getRegistryService() .getGovernanceSystemRegistry(MultitenantConstants.SUPER_TENANT_ID); } else { // both requested tenant and logged in user's tenant are carbon.super registry = this.registry; } } GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_PRODUCT_KEY); GenericArtifact apiProductArtifact = artifactManager.getGenericArtifact(uuid); if (apiProductArtifact != null) { return getApiProduct(registry, apiProductArtifact); } else { String msg = "Failed to get API Product. API Product artifact corresponding to artifactId " + uuid + " does not exist"; log.error(msg); throw new APIMgtResourceNotFoundException(msg); } } catch (RegistryException e) { String msg = "Failed to get API Product"; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get API Product"; log.error(msg, e); throw new APIManagementException(msg, e); } } /** * Get API Product by product identifier * * @param identifier APIProductIdentifier * @return API product identified by provider identifier * @throws APIManagementException */ public APIProduct getAPIProduct(APIProductIdentifier identifier) throws APIManagementException { String apiProductPath = APIUtil.getAPIProductPath(identifier); Registry registry; try { String productTenantDomain = MultitenantUtils .getTenantDomain(APIUtil.replaceEmailDomainBack(identifier.getProviderName())); int productTenantId = getTenantManager().getTenantId(productTenantDomain); if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(productTenantDomain)) { APIUtil.loadTenantRegistry(productTenantId); } if (this.tenantDomain == null || !this.tenantDomain.equals(productTenantDomain)) { //cross tenant scenario registry = getRegistryService().getGovernanceUserRegistry( getTenantAwareUsername(APIUtil.replaceEmailDomainBack(identifier.getProviderName())), productTenantId); } else { registry = this.registry; } GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_PRODUCT_KEY); Resource productResource = registry.get(apiProductPath); String artifactId = productResource.getUUID(); if (artifactId == null) { throw new APIManagementException("artifact id is null for : " + apiProductPath); } GenericArtifact productArtifact = artifactManager.getGenericArtifact(artifactId); APIProduct apiProduct = APIUtil.getAPIProduct(productArtifact, registry); //todo : implement visibility return apiProduct; } catch (RegistryException e) { String msg = "Failed to get API Product from : " + apiProductPath; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get API Product from : " + apiProductPath; log.error(msg, e); throw new APIManagementException(msg, e); } } @Override public Map<String, Object> searchPaginatedAPIProducts(String searchQuery, String requestedTenantDomain, int start, int end) throws APIManagementException { Map<String, Object> result = new HashMap<String, Object>(); boolean isTenantFlowStarted = false; if (log.isDebugEnabled()) { log.debug("Original search query received : " + searchQuery); } try { boolean isTenantMode = (requestedTenantDomain != null); if (isTenantMode && !org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME .equals(requestedTenantDomain)) { isTenantFlowStarted = true; startTenantFlow(requestedTenantDomain); } else { requestedTenantDomain = org.wso2.carbon.base.MultitenantConstants.SUPER_TENANT_DOMAIN_NAME; isTenantFlowStarted = true; startTenantFlow(requestedTenantDomain); } Registry userRegistry; int tenantIDLocal = 0; String userNameLocal = this.username; if ((isTenantMode && this.tenantDomain == null) || (isTenantMode && isTenantDomainNotMatching(requestedTenantDomain))) {//Tenant store anonymous mode tenantIDLocal = getTenantManager().getTenantId(requestedTenantDomain); userRegistry = getRegistryService() .getGovernanceUserRegistry(CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME, tenantIDLocal); userNameLocal = CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME; } else { userRegistry = this.registry; tenantIDLocal = tenantId; } PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(userNameLocal); result = searchPaginatedAPIProducts(userRegistry, getSearchQuery(searchQuery), start, end); } catch (Exception e) { String msg = "Failed to Search APIs"; log.error(msg, e); throw new APIManagementException(msg, e); } finally { if (isTenantFlowStarted) { endTenantFlow(); } } return result; } /** * Returns APIProduct Search result based on the provided query. * * @param registry * @param searchQuery Ex: provider=*admin* * @return APIProduct result * @throws APIManagementException */ public Map<String, Object> searchPaginatedAPIProducts(Registry registry, String searchQuery, int start, int end) throws APIManagementException { SortedSet<APIProduct> productSet = new TreeSet<APIProduct>(new APIProductNameComparator()); List<APIProduct> productList = new ArrayList<APIProduct>(); Map<String, Object> result = new HashMap<String, Object>(); int totalLength = 0; boolean isMore = false; try { //for now will use the same config for api products too todo: change this String paginationLimit = getAPIManagerConfiguration() .getFirstProperty(APIConstants.API_STORE_APIS_PER_PAGE); // If the Config exists use it to set the pagination limit final int maxPaginationLimit; if (paginationLimit != null) { // The additional 1 added to the maxPaginationLimit is to help us determine if more // APIs may exist so that we know that we are unable to determine the actual total // API count. We will subtract this 1 later on so that it does not interfere with // the logic of the rest of the application int pagination = Integer.parseInt(paginationLimit); // Because the store jaggery pagination logic is 10 results per a page we need to set pagination // limit to at least 11 or the pagination done at this level will conflict with the store pagination // leading to some of the APIs not being displayed if (pagination < 11) { pagination = 11; log.warn( "Value of '" + APIConstants.API_STORE_APIS_PER_PAGE + "' is too low, defaulting to 11"); } maxPaginationLimit = start + pagination + 1; } // Else if the config is not specified we go with default functionality and load all else { maxPaginationLimit = Integer.MAX_VALUE; } PaginationContext.init(start, end, "ASC", APIConstants.API_OVERVIEW_NAME, maxPaginationLimit); List<GovernanceArtifact> governanceArtifacts = GovernanceUtils.findGovernanceArtifacts( getSearchQuery(searchQuery), registry, APIConstants.API_PRODUCT_RXT_MEDIA_TYPE, true); totalLength = PaginationContext.getInstance().getLength(); boolean isFound = true; if (!isFound) { result.put("products", productSet); result.put("length", 0); result.put("isMore", isMore); return result; } // Check to see if we can speculate that there are more APIs to be loaded if (maxPaginationLimit == totalLength) { isMore = true; // More APIs exist, cannot determine total API count without incurring perf hit --totalLength; // Remove the additional 1 added earlier when setting max pagination limit } int tempLength = 0; for (GovernanceArtifact artifact : governanceArtifacts) { APIProduct resultAPIProduct = APIUtil.getAPIProduct(artifact, registry); if (resultAPIProduct != null) { productList.add(resultAPIProduct); } // Ensure the APIs returned matches the length, there could be an additional API // returned due incrementing the pagination limit when getting from registry tempLength++; if (tempLength >= totalLength) { break; } } productSet.addAll(productList); } catch (RegistryException e) { String msg = "Failed to search APIProducts with type"; log.error(msg, e); throw new APIManagementException(msg, e); } finally { PaginationContext.destroy(); } result.put("products", productSet); result.put("length", totalLength); result.put("isMore", isMore); return result; } protected APIProduct getApiProduct(Registry registry, GovernanceArtifact apiArtifact) throws APIManagementException { return APIUtil.getAPIProduct(apiArtifact, registry); } public List<APIProductResource> getResourcesOfAPIProduct(APIProductIdentifier productIdentifier) throws APIManagementException { return apiMgtDAO.getAPIProductResourceMappings(productIdentifier); } public ResourceFile getProductIcon(APIProductIdentifier identifier) throws APIManagementException { String thumbPath = APIUtil.getProductIconPath(identifier); String tenantDomain = MultitenantUtils .getTenantDomain(APIUtil.replaceEmailDomainBack(identifier.getProviderName())); Registry registry; boolean isTenantFlowStarted = false; try { if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { startTenantFlow(tenantDomain); isTenantFlowStarted = true; } /* If the API provider is a tenant, load tenant registry*/ if (tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(tenantDomain)) { int id = getTenantManager().getTenantId(tenantDomain); registry = getRegistryService().getGovernanceSystemRegistry(id); } else { if (this.tenantDomain != null && !MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(this.tenantDomain)) { registry = getRegistryService().getGovernanceUserRegistry(identifier.getProviderName(), MultitenantConstants.SUPER_TENANT_ID); } else { registry = this.registry; } } if (registry.resourceExists(thumbPath)) { Resource res = registry.get(thumbPath); return new ResourceFile(res.getContentStream(), res.getMediaType()); } } catch (RegistryException e) { String msg = "Error while loading API Product icon of API Product " + identifier.getName() + ":" + identifier.getVersion() + " from the registry"; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Error while loading API Product icon of API Product " + identifier.getName() + ":" + identifier.getVersion(); log.error(msg, e); throw new APIManagementException(msg, e); } finally { if (isTenantFlowStarted) { endTenantFlow(); } } return null; } @Override public String addProductResourceFile(String resourcePath, ResourceFile resourceFile) throws APIManagementException { //todo : implement access control checks here and move to userawareAPIProvider return addResourceFile(resourcePath, resourceFile); } /** * Get an api product documentation by artifact Id * * @param docId artifact id of the document * @param requestedTenantDomain tenant domain of the registry where the artifact is located * @return Document object which represents the artifact id * @throws APIManagementException */ public Documentation getProductDocumentation(String docId, String requestedTenantDomain) throws APIManagementException { Documentation documentation = null; try { Registry registryType; boolean isTenantMode = (requestedTenantDomain != null); //Tenant store anonymous mode if current tenant and the required tenant is not matching if ((isTenantMode && this.tenantDomain == null) || (isTenantMode && isTenantDomainNotMatching(requestedTenantDomain))) { int tenantId = getTenantManager().getTenantId(requestedTenantDomain); registryType = getRegistryService() .getGovernanceUserRegistry(CarbonConstants.REGISTRY_ANONNYMOUS_USERNAME, tenantId); } else { registryType = registry; } GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registryType, APIConstants.PRODUCT_DOCUMENTATION_KEY); GenericArtifact artifact = artifactManager.getGenericArtifact(docId); APIProductIdentifier productIdentifier = APIUtil.getProductIdentifier(artifact.getPath()); checkAccessControlPermission(productIdentifier); if (null != artifact) { documentation = APIUtil.getDocumentation(artifact); documentation.setCreatedDate(registryType.get(artifact.getPath()).getCreatedTime()); Date lastModified = registryType.get(artifact.getPath()).getLastModified(); if (lastModified != null) { documentation.setLastUpdated(registryType.get(artifact.getPath()).getLastModified()); } } } catch (RegistryException e) { String msg = "Failed to get documentation details"; log.error(msg, e); throw new APIManagementException(msg, e); } catch (org.wso2.carbon.user.api.UserStoreException e) { String msg = "Failed to get documentation details"; log.error(msg, e); throw new APIManagementException(msg, e); } return documentation; } public APIProduct getAPIProduct(String productPath) throws APIManagementException { try { GenericArtifactManager artifactManager = getAPIGenericArtifactManagerFromUtil(registry, APIConstants.API_PRODUCT_KEY); Resource productResource = registry.get(productPath); String artifactId = productResource.getUUID(); if (artifactId == null) { throw new APIManagementException("artifact id is null for : " + productPath); } GenericArtifact productArtifact = artifactManager.getGenericArtifact(artifactId); return APIUtil.getAPIProduct(productArtifact, registry); } catch (RegistryException e) { String msg = "Failed to get API Product from : " + productPath; log.error(msg, e); throw new APIManagementException(msg, e); } } @Override public String getAPIDefinitionOfAPIProduct(APIProduct product) throws APIManagementException { String resourcePath = APIUtil.getAPIProductOpenAPIDefinitionFilePath(product.getId()); JSONParser parser = new JSONParser(); String apiDocContent = null; try { if (registry.resourceExists(resourcePath + APIConstants.API_OAS_DEFINITION_RESOURCE_NAME)) { Resource apiDocResource = registry .get(resourcePath + APIConstants.API_OAS_DEFINITION_RESOURCE_NAME); apiDocContent = new String((byte[]) apiDocResource.getContent(), Charset.defaultCharset()); parser.parse(apiDocContent); } else { if (log.isDebugEnabled()) { log.debug("Resource " + APIConstants.API_OAS_DEFINITION_RESOURCE_NAME + " not found at " + resourcePath); } } } catch (RegistryException e) { handleException("Error while retrieving OpenAPI v2.0 or v3.0.0 Definition for " + product.getId().getName() + '-' + product.getId().getProviderName(), e); } catch (ParseException e) { handleException("Error while parsing OpenAPI v2.0 or v3.0.0 Definition for " + product.getId().getName() + '-' + product.getId().getProviderName() + " in " + resourcePath, e); } return apiDocContent; } }