Search in sources :

Example 86 with Subscription

use of org.wso2.carbon.apimgt.api.model.subscription.Subscription in project carbon-apimgt by wso2.

the class AlertSubscriptionsApiServiceImpl method subscribeForBotDetectionAlerts.

/**
 * Subscribe for bot detection alerts
 *
 * @param body           email to be registered for the subscription
 * @param messageContext CXF Message Context
 * @return alert subscription DTO containing the uuid of the subscription and the registered email
 * @throws APIManagementException if an error occurs when subscribing for bot detection alerts
 */
@Override
public Response subscribeForBotDetectionAlerts(BotDetectionAlertSubscriptionDTO body, MessageContext messageContext) throws APIManagementException {
    String email = body.getEmail();
    if (StringUtils.isBlank(email)) {
        String propertyName = AlertMgtConstants.BOT_DETECTION_EMAIL_FIELD;
        throw new APIManagementException(propertyName + " property value of payload cannot be blank", ExceptionCodes.from(ExceptionCodes.BLANK_PROPERTY_VALUE, propertyName));
    }
    APIAdmin apiAdmin = new APIAdminImpl();
    BotDetectionData alertSubscription = apiAdmin.getBotDetectionAlertSubscription(AlertMgtConstants.BOT_DETECTION_EMAIL_FIELD, email);
    if (alertSubscription != null) {
        RestApiUtil.handleResourceAlreadyExistsError("Email: " + email + " has already been subscribed for bot detection alerts", log);
    }
    apiAdmin.addBotDetectionAlertSubscription(email);
    BotDetectionData newAlertSubscription = apiAdmin.getBotDetectionAlertSubscription(AlertMgtConstants.BOT_DETECTION_EMAIL_FIELD, email);
    BotDetectionAlertSubscriptionDTO alertSubscriptionDTO = BotDetectionMappingUtil.fromAlertSubscriptionToDTO(newAlertSubscription);
    return Response.ok(alertSubscriptionDTO).build();
}
Also used : APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) APIAdmin(org.wso2.carbon.apimgt.api.APIAdmin) BotDetectionData(org.wso2.carbon.apimgt.api.model.botDataAPI.BotDetectionData) APIAdminImpl(org.wso2.carbon.apimgt.impl.APIAdminImpl) BotDetectionAlertSubscriptionDTO(org.wso2.carbon.apimgt.rest.api.admin.v1.dto.BotDetectionAlertSubscriptionDTO)

Example 87 with Subscription

use of org.wso2.carbon.apimgt.api.model.subscription.Subscription in project carbon-apimgt by wso2.

the class ApiMgtDAO method makeKeysForwardCompatible.

public void makeKeysForwardCompatible(ApiTypeWrapper apiTypeWrapper, List<API> oldAPIVersions) throws APIManagementException {
    // if there are no previous versions, there is no need to copy subscriptions
    if (oldAPIVersions == null || oldAPIVersions.isEmpty()) {
        return;
    }
    String getSubscriptionDataQuery = SQLConstants.GET_SUBSCRIPTION_DATA_SQL.replaceAll("_API_VERSION_LIST_", String.join(",", Collections.nCopies(oldAPIVersions.size(), "?")));
    APIIdentifier apiIdentifier = apiTypeWrapper.getApi().getId();
    try {
        // Retrieve all the existing subscription for the old version
        try (Connection connection = APIMgtDBUtil.getConnection()) {
            connection.setAutoCommit(false);
            try (PreparedStatement prepStmt = connection.prepareStatement(getSubscriptionDataQuery)) {
                prepStmt.setString(1, APIUtil.replaceEmailDomainBack(apiIdentifier.getProviderName()));
                prepStmt.setString(2, apiIdentifier.getApiName());
                int index = 3;
                for (API oldAPI : oldAPIVersions) {
                    prepStmt.setString(index++, oldAPI.getId().getVersion());
                }
                try (ResultSet rs = prepStmt.executeQuery()) {
                    List<SubscriptionInfo> subscriptionData = new ArrayList<SubscriptionInfo>();
                    while (rs.next() && !(APIConstants.SubscriptionStatus.ON_HOLD.equals(rs.getString("SUB_STATUS")))) {
                        int subscriptionId = rs.getInt("SUBSCRIPTION_ID");
                        String tierId = rs.getString("TIER_ID");
                        int applicationId = rs.getInt("APPLICATION_ID");
                        String apiVersion = rs.getString("VERSION");
                        String subscriptionStatus = rs.getString("SUB_STATUS");
                        SubscriptionInfo info = new SubscriptionInfo(subscriptionId, tierId, applicationId, apiVersion, subscriptionStatus);
                        subscriptionData.add(info);
                    }
                    // To keep track of already added subscriptions (apps)
                    List<Integer> addedApplications = new ArrayList<>();
                    for (int i = oldAPIVersions.size() - 1; i >= 0; i--) {
                        API oldAPI = oldAPIVersions.get(i);
                        for (SubscriptionInfo info : subscriptionData) {
                            try {
                                if (info.getApiVersion().equals(oldAPI.getId().getVersion()) && !addedApplications.contains(info.getApplicationId())) {
                                    String subscriptionStatus;
                                    if (APIConstants.SubscriptionStatus.BLOCKED.equalsIgnoreCase(info.getSubscriptionStatus())) {
                                        subscriptionStatus = APIConstants.SubscriptionStatus.BLOCKED;
                                    } else if (APIConstants.SubscriptionStatus.UNBLOCKED.equalsIgnoreCase(info.getSubscriptionStatus())) {
                                        subscriptionStatus = APIConstants.SubscriptionStatus.UNBLOCKED;
                                    } else if (APIConstants.SubscriptionStatus.PROD_ONLY_BLOCKED.equalsIgnoreCase(info.getSubscriptionStatus())) {
                                        subscriptionStatus = APIConstants.SubscriptionStatus.PROD_ONLY_BLOCKED;
                                    } else if (APIConstants.SubscriptionStatus.REJECTED.equalsIgnoreCase(info.getSubscriptionStatus())) {
                                        subscriptionStatus = APIConstants.SubscriptionStatus.REJECTED;
                                    } else {
                                        subscriptionStatus = APIConstants.SubscriptionStatus.ON_HOLD;
                                    }
                                    apiTypeWrapper.setTier(info.getTierId());
                                    Application application = getLightweightApplicationById(connection, info.getApplicationId());
                                    int subscriptionId = addSubscription(connection, apiTypeWrapper, application, subscriptionStatus, apiIdentifier.getProviderName());
                                    if (subscriptionId == -1) {
                                        String msg = "Unable to add a new subscription for the API: " + apiIdentifier.getName() + ":v" + apiIdentifier.getVersion();
                                        log.error(msg);
                                        throw new APIManagementException(msg);
                                    }
                                    addedApplications.add(info.getApplicationId());
                                }
                            // catching the exception because when copy the api without the option "require
                            // re-subscription"
                            // need to go forward rather throwing the exception
                            } catch (SubscriptionAlreadyExistingException e) {
                                log.error("Error while adding subscription " + e.getMessage(), e);
                            } catch (SubscriptionBlockedException e) {
                                log.info("Subscription is blocked: " + e.getMessage());
                            }
                        }
                    }
                }
                connection.commit();
            } catch (SQLException e) {
                connection.rollback();
                throw e;
            }
        }
    } catch (SQLException e) {
        handleException("Error when executing the SQL queries", e);
    }
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) ArrayList(java.util.ArrayList) PreparedStatement(java.sql.PreparedStatement) SubscriptionBlockedException(org.wso2.carbon.apimgt.api.SubscriptionBlockedException) APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) ResultSet(java.sql.ResultSet) SubscriptionAlreadyExistingException(org.wso2.carbon.apimgt.api.SubscriptionAlreadyExistingException) APIIdentifier(org.wso2.carbon.apimgt.api.model.APIIdentifier) SubscribedAPI(org.wso2.carbon.apimgt.api.model.SubscribedAPI) API(org.wso2.carbon.apimgt.api.model.API) Application(org.wso2.carbon.apimgt.api.model.Application)

Example 88 with Subscription

use of org.wso2.carbon.apimgt.api.model.subscription.Subscription in project carbon-apimgt by wso2.

the class ApiMgtDAO method getTopicSubscriptionsByApiUUID.

/**
 * Retrieves the web hook topc subscriptions from an application to a given api.
 *
 * @param applicationId application uuid
 * @param apiId         api uuid
 * @return set of web hook topic subscriptions
 * @throws APIManagementException
 */
public Set<Subscription> getTopicSubscriptionsByApiUUID(String applicationId, String apiId) throws APIManagementException {
    Connection conn = null;
    ResultSet resultSet = null;
    PreparedStatement ps = null;
    String getTopicSubscriptionsByApiIdQuery = SQLConstants.GET_WH_TOPIC_SUBSCRIPTIONS_BY_API_KEY;
    Set<Subscription> subscriptionSet = new HashSet();
    try {
        conn = APIMgtDBUtil.getConnection();
        ps = conn.prepareStatement(getTopicSubscriptionsByApiIdQuery);
        ps.setString(1, applicationId);
        ps.setString(2, apiId);
        resultSet = ps.executeQuery();
        while (resultSet.next()) {
            Subscription subscription = new Subscription();
            subscription.setApiUuid(resultSet.getString("API_UUID"));
            subscription.setCallback(resultSet.getString("HUB_CALLBACK_URL"));
            Timestamp deliveryTime = resultSet.getTimestamp("DELIVERED_AT");
            if (deliveryTime != null) {
                subscription.setLastDelivery(new Date(deliveryTime.getTime()));
            }
            subscription.setLastDeliveryState(resultSet.getInt("DELIVERY_STATE"));
            subscription.setTopic(resultSet.getString("HUB_TOPIC"));
            subscription.setAppID(resultSet.getString("APPLICATION_ID"));
            subscriptionSet.add(subscription);
        }
        return subscriptionSet;
    } catch (SQLException e) {
        handleException("Failed to retrieve topic subscriptions for application  " + applicationId, e);
    } finally {
        APIMgtDBUtil.closeAllConnections(ps, conn, resultSet);
    }
    return null;
}
Also used : SQLException(java.sql.SQLException) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) Subscription(org.wso2.carbon.apimgt.api.model.webhooks.Subscription) Timestamp(java.sql.Timestamp) Date(java.util.Date) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet)

Example 89 with Subscription

use of org.wso2.carbon.apimgt.api.model.subscription.Subscription in project carbon-apimgt by wso2.

the class ApiMgtDAO method getSubscriptionPolicies.

/**
 * Get all subscription level policeis belongs to specific tenant
 *
 * @param tenantID tenantID filters the polices belongs to specific tenant
 * @return subscriptionPolicy array list
 */
public SubscriptionPolicy[] getSubscriptionPolicies(int tenantID) throws APIManagementException {
    List<SubscriptionPolicy> policies = new ArrayList<SubscriptionPolicy>();
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    String sqlQuery = SQLConstants.GET_SUBSCRIPTION_POLICIES;
    if (forceCaseInsensitiveComparisons) {
        sqlQuery = SQLConstants.GET_SUBSCRIPTION_POLICIES;
    }
    try {
        conn = APIMgtDBUtil.getConnection();
        ps = conn.prepareStatement(sqlQuery);
        ps.setInt(1, tenantID);
        rs = ps.executeQuery();
        while (rs.next()) {
            SubscriptionPolicy subPolicy = new SubscriptionPolicy(rs.getString(ThrottlePolicyConstants.COLUMN_NAME));
            setCommonPolicyDetails(subPolicy, rs);
            subPolicy.setRateLimitCount(rs.getInt(ThrottlePolicyConstants.COLUMN_RATE_LIMIT_COUNT));
            subPolicy.setRateLimitTimeUnit(rs.getString(ThrottlePolicyConstants.COLUMN_RATE_LIMIT_TIME_UNIT));
            subPolicy.setSubscriberCount(rs.getInt(ThrottlePolicyConstants.COLUMN_CONNECTION_COUNT));
            subPolicy.setStopOnQuotaReach(rs.getBoolean(ThrottlePolicyConstants.COLUMN_STOP_ON_QUOTA_REACH));
            subPolicy.setBillingPlan(rs.getString(ThrottlePolicyConstants.COLUMN_BILLING_PLAN));
            subPolicy.setGraphQLMaxDepth(rs.getInt(ThrottlePolicyConstants.COLUMN_MAX_DEPTH));
            subPolicy.setGraphQLMaxComplexity(rs.getInt(ThrottlePolicyConstants.COLUMN_MAX_COMPLEXITY));
            subPolicy.setMonetizationPlan(rs.getString(ThrottlePolicyConstants.COLUMN_MONETIZATION_PLAN));
            Map<String, String> monetizationPlanProperties = subPolicy.getMonetizationPlanProperties();
            monetizationPlanProperties.put(APIConstants.Monetization.FIXED_PRICE, rs.getString(ThrottlePolicyConstants.COLUMN_FIXED_RATE));
            monetizationPlanProperties.put(APIConstants.Monetization.BILLING_CYCLE, rs.getString(ThrottlePolicyConstants.COLUMN_BILLING_CYCLE));
            monetizationPlanProperties.put(APIConstants.Monetization.PRICE_PER_REQUEST, rs.getString(ThrottlePolicyConstants.COLUMN_PRICE_PER_REQUEST));
            monetizationPlanProperties.put(APIConstants.Monetization.CURRENCY, rs.getString(ThrottlePolicyConstants.COLUMN_CURRENCY));
            subPolicy.setMonetizationPlanProperties(monetizationPlanProperties);
            InputStream binary = rs.getBinaryStream(ThrottlePolicyConstants.COLUMN_CUSTOM_ATTRIB);
            if (binary != null) {
                byte[] customAttrib = APIUtil.toByteArray(binary);
                subPolicy.setCustomAttributes(customAttrib);
            }
            policies.add(subPolicy);
        }
    } catch (SQLException e) {
        handleException("Error while executing SQL", e);
    } catch (IOException e) {
        handleException("Error while converting input stream to byte array", e);
    } finally {
        APIMgtDBUtil.closeAllConnections(ps, conn, rs);
    }
    return policies.toArray(new SubscriptionPolicy[policies.size()]);
}
Also used : SubscriptionPolicy(org.wso2.carbon.apimgt.api.model.policy.SubscriptionPolicy) SQLException(java.sql.SQLException) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) Connection(java.sql.Connection) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) IOException(java.io.IOException)

Example 90 with Subscription

use of org.wso2.carbon.apimgt.api.model.subscription.Subscription in project carbon-apimgt by wso2.

the class ApiMgtDAO method updateSubscriptionPolicy.

/**
 * Updates Subscription level policy.
 * <p>policy name and tenant id should be specified in <code>policy</code></p>
 *
 * @param policy updated policy object
 * @throws APIManagementException
 */
public void updateSubscriptionPolicy(SubscriptionPolicy policy) throws APIManagementException {
    Connection connection = null;
    PreparedStatement updateStatement = null;
    boolean hasCustomAttrib = false;
    String updateQuery;
    try {
        if (policy.getCustomAttributes() != null) {
            hasCustomAttrib = true;
        }
        if (!StringUtils.isBlank(policy.getPolicyName()) && policy.getTenantId() != -1) {
            updateQuery = SQLConstants.UPDATE_SUBSCRIPTION_POLICY_SQL;
            if (hasCustomAttrib) {
                updateQuery = SQLConstants.UPDATE_SUBSCRIPTION_POLICY_WITH_CUSTOM_ATTRIBUTES_SQL;
            }
        } else if (!StringUtils.isBlank(policy.getUUID())) {
            updateQuery = SQLConstants.UPDATE_SUBSCRIPTION_POLICY_BY_UUID_SQL;
            if (hasCustomAttrib) {
                updateQuery = SQLConstants.UPDATE_SUBSCRIPTION_POLICY_WITH_CUSTOM_ATTRIBUTES_BY_UUID_SQL;
            }
        } else {
            String errorMsg = "Policy object doesn't contain mandatory parameters. At least UUID or Name,Tenant Id" + " should be provided. Name: " + policy.getPolicyName() + ", Tenant Id: " + policy.getTenantId() + ", UUID: " + policy.getUUID();
            log.error(errorMsg);
            throw new APIManagementException(errorMsg);
        }
        connection = APIMgtDBUtil.getConnection();
        connection.setAutoCommit(false);
        updateStatement = connection.prepareStatement(updateQuery);
        if (!StringUtils.isEmpty(policy.getDisplayName())) {
            updateStatement.setString(1, policy.getDisplayName());
        } else {
            updateStatement.setString(1, policy.getPolicyName());
        }
        updateStatement.setString(2, policy.getDescription());
        updateStatement.setString(3, policy.getDefaultQuotaPolicy().getType());
        if (PolicyConstants.REQUEST_COUNT_TYPE.equalsIgnoreCase(policy.getDefaultQuotaPolicy().getType())) {
            RequestCountLimit limit = (RequestCountLimit) policy.getDefaultQuotaPolicy().getLimit();
            updateStatement.setLong(4, limit.getRequestCount());
            updateStatement.setString(5, null);
        } else if (PolicyConstants.BANDWIDTH_TYPE.equalsIgnoreCase(policy.getDefaultQuotaPolicy().getType())) {
            BandwidthLimit limit = (BandwidthLimit) policy.getDefaultQuotaPolicy().getLimit();
            updateStatement.setLong(4, limit.getDataAmount());
            updateStatement.setString(5, limit.getDataUnit());
        } else if (PolicyConstants.EVENT_COUNT_TYPE.equalsIgnoreCase(policy.getDefaultQuotaPolicy().getType())) {
            EventCountLimit limit = (EventCountLimit) policy.getDefaultQuotaPolicy().getLimit();
            updateStatement.setLong(4, limit.getEventCount());
            updateStatement.setString(5, null);
        }
        updateStatement.setLong(6, policy.getDefaultQuotaPolicy().getLimit().getUnitTime());
        updateStatement.setString(7, policy.getDefaultQuotaPolicy().getLimit().getTimeUnit());
        updateStatement.setInt(8, policy.getRateLimitCount());
        updateStatement.setString(9, policy.getRateLimitTimeUnit());
        updateStatement.setBoolean(10, policy.isStopOnQuotaReach());
        updateStatement.setInt(11, policy.getGraphQLMaxDepth());
        updateStatement.setInt(12, policy.getGraphQLMaxComplexity());
        updateStatement.setString(13, policy.getBillingPlan());
        if (hasCustomAttrib) {
            long lengthOfStream = policy.getCustomAttributes().length;
            updateStatement.setBinaryStream(14, new ByteArrayInputStream(policy.getCustomAttributes()), lengthOfStream);
            if (!StringUtils.isBlank(policy.getPolicyName()) && policy.getTenantId() != -1) {
                updateStatement.setString(15, policy.getMonetizationPlan());
                updateStatement.setString(16, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.FIXED_PRICE));
                updateStatement.setString(17, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.BILLING_CYCLE));
                updateStatement.setString(18, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.PRICE_PER_REQUEST));
                updateStatement.setString(19, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.CURRENCY));
                updateStatement.setInt(20, policy.getSubscriberCount());
                updateStatement.setString(21, policy.getPolicyName());
                updateStatement.setInt(22, policy.getTenantId());
            } else if (!StringUtils.isBlank(policy.getUUID())) {
                updateStatement.setString(15, policy.getMonetizationPlan());
                updateStatement.setString(16, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.FIXED_PRICE));
                updateStatement.setString(17, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.BILLING_CYCLE));
                updateStatement.setString(18, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.PRICE_PER_REQUEST));
                updateStatement.setString(19, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.CURRENCY));
                updateStatement.setInt(20, policy.getSubscriberCount());
                updateStatement.setString(21, policy.getUUID());
            }
        } else {
            if (!StringUtils.isBlank(policy.getPolicyName()) && policy.getTenantId() != -1) {
                updateStatement.setString(14, policy.getMonetizationPlan());
                updateStatement.setString(15, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.FIXED_PRICE));
                updateStatement.setString(16, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.BILLING_CYCLE));
                updateStatement.setString(17, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.PRICE_PER_REQUEST));
                updateStatement.setString(18, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.CURRENCY));
                updateStatement.setInt(19, policy.getSubscriberCount());
                updateStatement.setString(20, policy.getPolicyName());
                updateStatement.setInt(21, policy.getTenantId());
            } else if (!StringUtils.isBlank(policy.getUUID())) {
                updateStatement.setString(14, policy.getMonetizationPlan());
                updateStatement.setString(15, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.FIXED_PRICE));
                updateStatement.setString(16, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.BILLING_CYCLE));
                updateStatement.setString(17, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.PRICE_PER_REQUEST));
                updateStatement.setString(18, policy.getMonetizationPlanProperties().get(APIConstants.Monetization.CURRENCY));
                updateStatement.setInt(19, policy.getSubscriberCount());
                updateStatement.setString(20, policy.getUUID());
            }
        }
        updateStatement.executeUpdate();
        connection.commit();
    } catch (SQLException e) {
        if (connection != null) {
            try {
                connection.rollback();
            } catch (SQLException ex) {
                // Rollback failed. Exception will be thrown later for upper exception
                log.error("Failed to rollback the update Subscription Policy: " + policy.toString(), ex);
            }
        }
        handleException("Failed to update subscription policy: " + policy.getPolicyName() + '-' + policy.getTenantId(), e);
    } finally {
        APIMgtDBUtil.closeAllConnections(updateStatement, connection, null);
    }
}
Also used : RequestCountLimit(org.wso2.carbon.apimgt.api.model.policy.RequestCountLimit) EventCountLimit(org.wso2.carbon.apimgt.api.model.policy.EventCountLimit) APIManagementException(org.wso2.carbon.apimgt.api.APIManagementException) ByteArrayInputStream(java.io.ByteArrayInputStream) SQLException(java.sql.SQLException) Connection(java.sql.Connection) PreparedStatement(java.sql.PreparedStatement) BandwidthLimit(org.wso2.carbon.apimgt.api.model.policy.BandwidthLimit)

Aggregations

APIManagementException (org.wso2.carbon.apimgt.api.APIManagementException)79 ArrayList (java.util.ArrayList)69 Test (org.testng.annotations.Test)58 Subscription (org.wso2.carbon.apimgt.core.models.Subscription)58 Test (org.junit.Test)56 SQLException (java.sql.SQLException)55 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)51 Connection (java.sql.Connection)49 PreparedStatement (java.sql.PreparedStatement)48 ResultSet (java.sql.ResultSet)39 SubscriptionPolicy (org.wso2.carbon.apimgt.core.models.policy.SubscriptionPolicy)37 APIManagementException (org.wso2.carbon.apimgt.core.exception.APIManagementException)35 APISubscriptionDAO (org.wso2.carbon.apimgt.core.dao.APISubscriptionDAO)34 APIMgtDAOException (org.wso2.carbon.apimgt.core.exception.APIMgtDAOException)34 SubscribedAPI (org.wso2.carbon.apimgt.api.model.SubscribedAPI)31 Application (org.wso2.carbon.apimgt.core.models.Application)30 API (org.wso2.carbon.apimgt.core.models.API)28 Response (javax.ws.rs.core.Response)24 Application (org.wso2.carbon.apimgt.api.model.Application)22 APIPublisher (org.wso2.carbon.apimgt.core.api.APIPublisher)22