Java tutorial
/* * Copyright 2014 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.apiman.manager.api.rest.impl; import io.apiman.common.util.AesEncrypter; import io.apiman.gateway.engine.beans.ServiceEndpoint; import io.apiman.manager.api.beans.BeanUtils; import io.apiman.manager.api.beans.apps.ApplicationBean; import io.apiman.manager.api.beans.apps.ApplicationStatus; import io.apiman.manager.api.beans.apps.ApplicationVersionBean; import io.apiman.manager.api.beans.apps.NewApplicationBean; import io.apiman.manager.api.beans.apps.NewApplicationVersionBean; import io.apiman.manager.api.beans.apps.UpdateApplicationBean; import io.apiman.manager.api.beans.audit.AuditEntryBean; import io.apiman.manager.api.beans.audit.data.EntityUpdatedData; import io.apiman.manager.api.beans.audit.data.MembershipData; import io.apiman.manager.api.beans.contracts.ContractBean; import io.apiman.manager.api.beans.contracts.NewContractBean; import io.apiman.manager.api.beans.gateways.GatewayBean; import io.apiman.manager.api.beans.idm.GrantRolesBean; import io.apiman.manager.api.beans.idm.PermissionType; import io.apiman.manager.api.beans.idm.RoleBean; import io.apiman.manager.api.beans.idm.RoleMembershipBean; import io.apiman.manager.api.beans.idm.UserBean; import io.apiman.manager.api.beans.members.MemberBean; import io.apiman.manager.api.beans.members.MemberRoleBean; import io.apiman.manager.api.beans.metrics.HistogramIntervalType; import io.apiman.manager.api.beans.metrics.ResponseStatsHistogramBean; import io.apiman.manager.api.beans.metrics.ResponseStatsPerAppBean; import io.apiman.manager.api.beans.metrics.ResponseStatsPerPlanBean; import io.apiman.manager.api.beans.metrics.ResponseStatsSummaryBean; import io.apiman.manager.api.beans.metrics.UsageHistogramBean; import io.apiman.manager.api.beans.metrics.UsagePerAppBean; import io.apiman.manager.api.beans.metrics.UsagePerPlanBean; import io.apiman.manager.api.beans.orgs.NewOrganizationBean; import io.apiman.manager.api.beans.orgs.OrganizationBean; import io.apiman.manager.api.beans.orgs.UpdateOrganizationBean; import io.apiman.manager.api.beans.plans.NewPlanBean; import io.apiman.manager.api.beans.plans.NewPlanVersionBean; import io.apiman.manager.api.beans.plans.PlanBean; import io.apiman.manager.api.beans.plans.PlanStatus; import io.apiman.manager.api.beans.plans.PlanVersionBean; import io.apiman.manager.api.beans.plans.UpdatePlanBean; import io.apiman.manager.api.beans.policies.NewPolicyBean; import io.apiman.manager.api.beans.policies.PolicyBean; import io.apiman.manager.api.beans.policies.PolicyChainBean; import io.apiman.manager.api.beans.policies.PolicyDefinitionBean; import io.apiman.manager.api.beans.policies.PolicyType; import io.apiman.manager.api.beans.policies.UpdatePolicyBean; import io.apiman.manager.api.beans.search.PagingBean; import io.apiman.manager.api.beans.search.SearchCriteriaBean; import io.apiman.manager.api.beans.search.SearchCriteriaFilterOperator; import io.apiman.manager.api.beans.search.SearchResultsBean; import io.apiman.manager.api.beans.services.NewServiceBean; import io.apiman.manager.api.beans.services.NewServiceVersionBean; import io.apiman.manager.api.beans.services.ServiceBean; import io.apiman.manager.api.beans.services.ServiceDefinitionType; import io.apiman.manager.api.beans.services.ServiceGatewayBean; import io.apiman.manager.api.beans.services.ServicePlanBean; import io.apiman.manager.api.beans.services.ServiceStatus; import io.apiman.manager.api.beans.services.ServiceVersionBean; import io.apiman.manager.api.beans.services.UpdateServiceBean; import io.apiman.manager.api.beans.services.UpdateServiceVersionBean; import io.apiman.manager.api.beans.summary.ApiEntryBean; import io.apiman.manager.api.beans.summary.ApiRegistryBean; import io.apiman.manager.api.beans.summary.ApplicationSummaryBean; import io.apiman.manager.api.beans.summary.ApplicationVersionSummaryBean; import io.apiman.manager.api.beans.summary.ContractSummaryBean; import io.apiman.manager.api.beans.summary.GatewaySummaryBean; import io.apiman.manager.api.beans.summary.PlanSummaryBean; import io.apiman.manager.api.beans.summary.PlanVersionSummaryBean; import io.apiman.manager.api.beans.summary.PolicySummaryBean; import io.apiman.manager.api.beans.summary.ServicePlanSummaryBean; import io.apiman.manager.api.beans.summary.ServiceSummaryBean; import io.apiman.manager.api.beans.summary.ServiceVersionEndpointSummaryBean; import io.apiman.manager.api.beans.summary.ServiceVersionSummaryBean; import io.apiman.manager.api.core.IApiKeyGenerator; import io.apiman.manager.api.core.IApplicationValidator; import io.apiman.manager.api.core.IIdmStorage; import io.apiman.manager.api.core.IMetricsAccessor; import io.apiman.manager.api.core.IServiceValidator; import io.apiman.manager.api.core.IStorage; import io.apiman.manager.api.core.IStorageQuery; import io.apiman.manager.api.core.exceptions.StorageException; import io.apiman.manager.api.core.logging.ApimanLogger; import io.apiman.manager.api.core.logging.IApimanLogger; import io.apiman.manager.api.core.util.PolicyTemplateUtil; import io.apiman.manager.api.gateway.GatewayAuthenticationException; import io.apiman.manager.api.gateway.IGatewayLink; import io.apiman.manager.api.gateway.IGatewayLinkFactory; import io.apiman.manager.api.rest.contract.IOrganizationResource; import io.apiman.manager.api.rest.contract.IRoleResource; import io.apiman.manager.api.rest.contract.IUserResource; import io.apiman.manager.api.rest.contract.exceptions.AbstractRestException; import io.apiman.manager.api.rest.contract.exceptions.ApplicationAlreadyExistsException; import io.apiman.manager.api.rest.contract.exceptions.ApplicationNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.ApplicationVersionNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.ContractAlreadyExistsException; import io.apiman.manager.api.rest.contract.exceptions.ContractNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.GatewayNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.InvalidMetricCriteriaException; import io.apiman.manager.api.rest.contract.exceptions.InvalidServiceStatusException; import io.apiman.manager.api.rest.contract.exceptions.NotAuthorizedException; import io.apiman.manager.api.rest.contract.exceptions.OrganizationAlreadyExistsException; import io.apiman.manager.api.rest.contract.exceptions.OrganizationNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.PlanAlreadyExistsException; import io.apiman.manager.api.rest.contract.exceptions.PlanNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.PlanVersionNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.PolicyDefinitionNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.PolicyNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.RoleNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.ServiceAlreadyExistsException; import io.apiman.manager.api.rest.contract.exceptions.ServiceDefinitionNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.ServiceNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.ServiceVersionNotFoundException; import io.apiman.manager.api.rest.contract.exceptions.SystemErrorException; import io.apiman.manager.api.rest.contract.exceptions.UserNotFoundException; import io.apiman.manager.api.rest.impl.audit.AuditUtils; import io.apiman.manager.api.rest.impl.i18n.Messages; import io.apiman.manager.api.rest.impl.util.ExceptionFactory; import io.apiman.manager.api.security.ISecurityContext; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.ISODateTimeFormat; /** * Implementation of the Organization API. * * @author eric.wittmann@redhat.com */ @RequestScoped public class OrganizationResourceImpl implements IOrganizationResource { @SuppressWarnings("nls") public static final String[] DATE_FORMATS = { "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd'T'HH:mm:ssz", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm", "yyyy-MM-dd", "EEE, dd MMM yyyy HH:mm:ss z", "EEE, dd MMM yyyy HH:mm:ss", "EEE, dd MMM yyyy" }; private static final long ONE_MINUTE_MILLIS = 1 * 60 * 1000; private static final long ONE_HOUR_MILLIS = 1 * 60 * 60 * 1000; private static final long ONE_DAY_MILLIS = 1 * 24 * 60 * 60 * 1000; private static final long ONE_WEEK_MILLIS = 7 * 24 * 60 * 60 * 1000; private static final long ONE_MONTH_MILLIS = 30 * 24 * 60 * 60 * 1000; @Inject IStorage storage; @Inject IIdmStorage idmStorage; @Inject IStorageQuery query; @Inject IMetricsAccessor metrics; @Inject IApplicationValidator applicationValidator; @Inject IServiceValidator serviceValidator; @Inject IApiKeyGenerator apiKeyGenerator; @Inject IUserResource users; @Inject IRoleResource roles; @Inject ISecurityContext securityContext; @Inject IGatewayLinkFactory gatewayLinkFactory; @Context HttpServletRequest request; @Inject @ApimanLogger(OrganizationResourceImpl.class) IApimanLogger log; /** * Constructor. */ public OrganizationResourceImpl() { } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#create(io.apiman.manager.api.beans.orgs.NewOrganizationBean) */ @Override public OrganizationBean create(NewOrganizationBean bean) throws OrganizationAlreadyExistsException { List<RoleBean> autoGrantedRoles = null; SearchCriteriaBean criteria = new SearchCriteriaBean(); criteria.setPage(1); criteria.setPageSize(100); criteria.addFilter("autoGrant", "true", SearchCriteriaFilterOperator.bool_eq); //$NON-NLS-1$ //$NON-NLS-2$ try { autoGrantedRoles = idmStorage.findRoles(criteria).getBeans(); } catch (StorageException e) { throw new SystemErrorException(e); } if ("true".equals(System.getProperty("apiman.manager.require-auto-granted-org", "true"))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (autoGrantedRoles.isEmpty()) { throw new SystemErrorException( Messages.i18n.format("OrganizationResourceImpl.NoAutoGrantRoleAvailable")); //$NON-NLS-1$ } } OrganizationBean orgBean = new OrganizationBean(); orgBean.setName(bean.getName()); orgBean.setDescription(bean.getDescription()); orgBean.setId(BeanUtils.idFromName(bean.getName())); orgBean.setCreatedOn(new Date()); orgBean.setCreatedBy(securityContext.getCurrentUser()); orgBean.setModifiedOn(new Date()); orgBean.setModifiedBy(securityContext.getCurrentUser()); try { // Store/persist the new organization storage.beginTx(); if (storage.getOrganization(orgBean.getId()) != null) { throw ExceptionFactory.organizationAlreadyExistsException(bean.getName()); } storage.createOrganization(orgBean); storage.createAuditEntry(AuditUtils.organizationCreated(orgBean, securityContext)); storage.commitTx(); // Auto-grant memberships in roles to the creator of the organization for (RoleBean roleBean : autoGrantedRoles) { String currentUser = securityContext.getCurrentUser(); String orgId = orgBean.getId(); RoleMembershipBean membership = RoleMembershipBean.create(currentUser, roleBean.getId(), orgId); membership.setCreatedOn(new Date()); idmStorage.createMembership(membership); } log.debug(String.format("Created organization %s: %s", orgBean.getName(), orgBean)); //$NON-NLS-1$ return orgBean; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#get(java.lang.String) */ @Override public OrganizationBean get(String organizationId) throws OrganizationNotFoundException, NotAuthorizedException { try { storage.beginTx(); OrganizationBean organizationBean = storage.getOrganization(organizationId); if (organizationBean == null) { throw ExceptionFactory.organizationNotFoundException(organizationId); } storage.commitTx(); log.debug(String.format("Got organization %s: %s", organizationBean.getName(), organizationBean)); //$NON-NLS-1$ return organizationBean; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#update(java.lang.String, io.apiman.manager.api.beans.orgs.UpdateOrganizationBean) */ @Override public void update(String organizationId, UpdateOrganizationBean bean) throws OrganizationNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.orgEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); try { storage.beginTx(); OrganizationBean orgForUpdate = storage.getOrganization(organizationId); if (orgForUpdate == null) { throw ExceptionFactory.organizationNotFoundException(organizationId); } EntityUpdatedData auditData = new EntityUpdatedData(); if (AuditUtils.valueChanged(orgForUpdate.getDescription(), bean.getDescription())) { auditData.addChange("description", orgForUpdate.getDescription(), bean.getDescription()); //$NON-NLS-1$ orgForUpdate.setDescription(bean.getDescription()); } storage.updateOrganization(orgForUpdate); storage.createAuditEntry(AuditUtils.organizationUpdated(orgForUpdate, auditData, securityContext)); storage.commitTx(); log.debug(String.format("Updated organization %s: %s", orgForUpdate.getName(), orgForUpdate)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#activity(java.lang.String, int, int) */ @Override public SearchResultsBean<AuditEntryBean> activity(String organizationId, int page, int pageSize) throws OrganizationNotFoundException, NotAuthorizedException { if (page <= 1) { page = 1; } if (pageSize == 0) { pageSize = 20; } try { SearchResultsBean<AuditEntryBean> rval = null; PagingBean paging = new PagingBean(); paging.setPage(page); paging.setPageSize(pageSize); rval = query.auditEntity(organizationId, null, null, null, paging); return rval; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createApp(java.lang.String, io.apiman.manager.api.beans.apps.NewApplicationBean) */ @Override public ApplicationBean createApp(String organizationId, NewApplicationBean bean) throws OrganizationNotFoundException, ApplicationAlreadyExistsException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); ApplicationBean newApp = new ApplicationBean(); newApp.setId(BeanUtils.idFromName(bean.getName())); newApp.setName(bean.getName()); newApp.setDescription(bean.getDescription()); newApp.setCreatedBy(securityContext.getCurrentUser()); newApp.setCreatedOn(new Date()); try { // Store/persist the new application storage.beginTx(); OrganizationBean org = storage.getOrganization(organizationId); if (org == null) { throw ExceptionFactory.organizationNotFoundException(organizationId); } newApp.setOrganization(org); if (storage.getApplication(org.getId(), newApp.getId()) != null) { throw ExceptionFactory.organizationAlreadyExistsException(bean.getName()); } storage.createApplication(newApp); storage.createAuditEntry(AuditUtils.applicationCreated(newApp, securityContext)); if (bean.getInitialVersion() != null) { NewApplicationVersionBean newAppVersion = new NewApplicationVersionBean(); newAppVersion.setVersion(bean.getInitialVersion()); createAppVersionInternal(newAppVersion, newApp); } storage.commitTx(); log.debug(String.format("Created application %s: %s", newApp.getName(), newApp)); //$NON-NLS-1$ return newApp; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getApp(java.lang.String, java.lang.String) */ @Override public ApplicationBean getApp(String organizationId, String applicationId) throws ApplicationNotFoundException, NotAuthorizedException { try { storage.beginTx(); ApplicationBean applicationBean = storage.getApplication(organizationId, applicationId); if (applicationBean == null) { throw ExceptionFactory.applicationNotFoundException(applicationId); } storage.commitTx(); log.debug(String.format("Got application %s: %s", applicationBean.getName(), applicationBean)); //$NON-NLS-1$ return applicationBean; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getAppActivity(java.lang.String, java.lang.String, int, int) */ @Override public SearchResultsBean<AuditEntryBean> getAppActivity(String organizationId, String applicationId, int page, int pageSize) throws ApplicationNotFoundException, NotAuthorizedException { if (page <= 1) { page = 1; } if (pageSize == 0) { pageSize = 20; } try { SearchResultsBean<AuditEntryBean> rval = null; PagingBean paging = new PagingBean(); paging.setPage(page); paging.setPageSize(pageSize); rval = query.auditEntity(organizationId, applicationId, null, ApplicationBean.class, paging); return rval; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listApps(java.lang.String) */ @Override public List<ApplicationSummaryBean> listApps(String organizationId) throws OrganizationNotFoundException, NotAuthorizedException { get(organizationId); try { return query.getApplicationsInOrg(organizationId); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#updateApp(java.lang.String, java.lang.String, io.apiman.manager.api.beans.apps.UpdateApplicationBean) */ @Override public void updateApp(String organizationId, String applicationId, UpdateApplicationBean bean) throws ApplicationNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); try { storage.beginTx(); ApplicationBean appForUpdate = storage.getApplication(organizationId, applicationId); if (appForUpdate == null) { throw ExceptionFactory.applicationNotFoundException(applicationId); } EntityUpdatedData auditData = new EntityUpdatedData(); if (AuditUtils.valueChanged(appForUpdate.getDescription(), bean.getDescription())) { auditData.addChange("description", appForUpdate.getDescription(), bean.getDescription()); //$NON-NLS-1$ appForUpdate.setDescription(bean.getDescription()); } storage.updateApplication(appForUpdate); storage.createAuditEntry(AuditUtils.applicationUpdated(appForUpdate, auditData, securityContext)); storage.commitTx(); log.debug(String.format("Updated application %s: %s", appForUpdate.getName(), appForUpdate)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createAppVersion(java.lang.String, java.lang.String, io.apiman.manager.api.beans.apps.NewApplicationVersionBean) */ @Override public ApplicationVersionBean createAppVersion(String organizationId, String applicationId, NewApplicationVersionBean bean) throws ApplicationNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); ApplicationVersionBean newVersion; try { storage.beginTx(); ApplicationBean application = storage.getApplication(organizationId, applicationId); if (application == null) { throw ExceptionFactory.applicationNotFoundException(applicationId); } newVersion = createAppVersionInternal(bean, application); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } if (bean.isClone() && bean.getCloneVersion() != null) { try { List<ContractSummaryBean> contracts = getApplicationVersionContracts(organizationId, applicationId, bean.getCloneVersion()); for (ContractSummaryBean contract : contracts) { NewContractBean ncb = new NewContractBean(); ncb.setPlanId(contract.getPlanId()); ncb.setServiceId(contract.getServiceId()); ncb.setServiceOrgId(contract.getServiceOrganizationId()); ncb.setServiceVersion(contract.getServiceVersion()); createContract(organizationId, applicationId, newVersion.getVersion(), ncb); } List<PolicySummaryBean> policies = listAppPolicies(organizationId, applicationId, bean.getCloneVersion()); for (PolicySummaryBean policySummary : policies) { PolicyBean policy = getAppPolicy(organizationId, applicationId, bean.getCloneVersion(), policySummary.getId()); NewPolicyBean npb = new NewPolicyBean(); npb.setDefinitionId(policy.getDefinition().getId()); npb.setConfiguration(policy.getConfiguration()); createAppPolicy(organizationId, applicationId, newVersion.getVersion(), npb); } } catch (Exception e) { // TODO it's ok if the clone fails - we did our best } } return newVersion; } /** * Creates a new application version. * @param bean * @param application * @throws StorageException */ protected ApplicationVersionBean createAppVersionInternal(NewApplicationVersionBean bean, ApplicationBean application) throws StorageException { if (!BeanUtils.isValidVersion(bean.getVersion())) { throw new StorageException("Invalid/illegal application version: " + bean.getVersion()); //$NON-NLS-1$ } ApplicationVersionBean newVersion = new ApplicationVersionBean(); newVersion.setApplication(application); newVersion.setCreatedBy(securityContext.getCurrentUser()); newVersion.setCreatedOn(new Date()); newVersion.setModifiedBy(securityContext.getCurrentUser()); newVersion.setModifiedOn(new Date()); newVersion.setStatus(ApplicationStatus.Created); newVersion.setVersion(bean.getVersion()); storage.createApplicationVersion(newVersion); storage.createAuditEntry(AuditUtils.applicationVersionCreated(newVersion, securityContext)); log.debug(String.format("Created new application version %s: %s", newVersion.getApplication().getName(), //$NON-NLS-1$ newVersion)); return newVersion; } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getAppVersion(java.lang.String, java.lang.String, java.lang.String) */ @Override public ApplicationVersionBean getAppVersion(String organizationId, String applicationId, String version) throws ApplicationVersionNotFoundException, NotAuthorizedException { try { storage.beginTx(); ApplicationVersionBean applicationVersion = storage.getApplicationVersion(organizationId, applicationId, version); if (applicationVersion == null) throw ExceptionFactory.applicationVersionNotFoundException(applicationId, version); storage.commitTx(); log.debug(String.format("Got new application version %s: %s", //$NON-NLS-1$ applicationVersion.getApplication().getName(), applicationVersion)); return applicationVersion; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getAppVersionActivity(java.lang.String, java.lang.String, java.lang.String, int, int) */ @Override public SearchResultsBean<AuditEntryBean> getAppVersionActivity(String organizationId, String applicationId, String version, int page, int pageSize) throws ApplicationVersionNotFoundException, NotAuthorizedException { if (page <= 1) { page = 1; } if (pageSize == 0) { pageSize = 20; } try { SearchResultsBean<AuditEntryBean> rval = null; PagingBean paging = new PagingBean(); paging.setPage(page); paging.setPageSize(pageSize); rval = query.auditEntity(organizationId, applicationId, version, ApplicationBean.class, paging); return rval; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listAppVersions(java.lang.String, java.lang.String) */ @Override public List<ApplicationVersionSummaryBean> listAppVersions(String organizationId, String applicationId) throws ApplicationNotFoundException, NotAuthorizedException { // Try to get the application first - will throw a ApplicationNotFoundException if not found. getApp(organizationId, applicationId); try { return query.getApplicationVersions(organizationId, applicationId); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createContract(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.contracts.NewContractBean) */ @Override public ContractBean createContract(String organizationId, String applicationId, String version, NewContractBean bean) throws OrganizationNotFoundException, ApplicationNotFoundException, ServiceNotFoundException, PlanNotFoundException, ContractAlreadyExistsException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); try { storage.beginTx(); ContractBean contract = createContractInternal(organizationId, applicationId, version, bean); storage.commitTx(); log.debug(String.format("Created new contract %s: %s", contract.getId(), contract)); //$NON-NLS-1$ return contract; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); // Up above we are optimistically creating the contract. If it fails, check to see // if it failed because it was a duplicate. If so, throw something sensible. We // only do this on failure (we would get a FK contraint failure, for example) to // reduce overhead on the typical happy path. if (contractAlreadyExists(organizationId, applicationId, version, bean)) { throw ExceptionFactory.contractAlreadyExistsException(); } else { throw new SystemErrorException(e); } } } /** * Creates a contract. * @param organizationId * @param applicationId * @param version * @param bean * @throws StorageException * @throws Exception */ protected ContractBean createContractInternal(String organizationId, String applicationId, String version, NewContractBean bean) throws StorageException, Exception { ContractBean contract; ApplicationVersionBean avb; avb = storage.getApplicationVersion(organizationId, applicationId, version); if (avb == null) { throw ExceptionFactory.applicationNotFoundException(applicationId); } if (avb.getStatus() == ApplicationStatus.Registered || avb.getStatus() == ApplicationStatus.Retired) { throw ExceptionFactory.invalidApplicationStatusException(); } ServiceVersionBean svb = storage.getServiceVersion(bean.getServiceOrgId(), bean.getServiceId(), bean.getServiceVersion()); if (svb == null) { throw ExceptionFactory.serviceNotFoundException(bean.getServiceId()); } if (svb.getStatus() != ServiceStatus.Published) { throw ExceptionFactory.invalidServiceStatusException(); } Set<ServicePlanBean> plans = svb.getPlans(); String planVersion = null; if (plans != null) { for (ServicePlanBean servicePlanBean : plans) { if (servicePlanBean.getPlanId().equals(bean.getPlanId())) { planVersion = servicePlanBean.getVersion(); } } } if (planVersion == null) { throw ExceptionFactory.planNotFoundException(bean.getPlanId()); } PlanVersionBean pvb = storage.getPlanVersion(bean.getServiceOrgId(), bean.getPlanId(), planVersion); if (pvb == null) { throw ExceptionFactory.planNotFoundException(bean.getPlanId()); } if (pvb.getStatus() != PlanStatus.Locked) { throw ExceptionFactory.invalidPlanStatusException(); } contract = new ContractBean(); contract.setApplication(avb); contract.setService(svb); contract.setPlan(pvb); contract.setCreatedBy(securityContext.getCurrentUser()); contract.setCreatedOn(new Date()); contract.setApikey(apiKeyGenerator.generate()); // Validate the state of the application. if (applicationValidator.isReady(avb, true)) { avb.setStatus(ApplicationStatus.Ready); } storage.createContract(contract); storage.createAuditEntry(AuditUtils.contractCreatedFromApp(contract, securityContext)); storage.createAuditEntry(AuditUtils.contractCreatedToService(contract, securityContext)); // Update the version with new meta-data (e.g. modified-by) avb.setModifiedBy(securityContext.getCurrentUser()); avb.setModifiedOn(new Date()); storage.updateApplicationVersion(avb); return contract; } /** * Check to see if the contract already exists, by getting a list of all the * application's contracts and comparing with the one being created. * @param organizationId * @param applicationId * @param version * @param bean */ private boolean contractAlreadyExists(String organizationId, String applicationId, String version, NewContractBean bean) { try { List<ContractSummaryBean> contracts = query.getApplicationContracts(organizationId, applicationId, version); for (ContractSummaryBean contract : contracts) { if (contract.getServiceOrganizationId().equals(bean.getServiceOrgId()) && contract.getServiceId().equals(bean.getServiceId()) && contract.getServiceVersion().equals(bean.getServiceVersion()) && contract.getPlanId().equals(bean.getPlanId())) { return true; } } return false; } catch (StorageException e) { return false; } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getContract(java.lang.String, java.lang.String, java.lang.String, java.lang.Long) */ @Override public ContractBean getContract(String organizationId, String applicationId, String version, Long contractId) throws ApplicationNotFoundException, ContractNotFoundException, NotAuthorizedException { boolean hasPermission = securityContext.hasPermission(PermissionType.appView, organizationId); try { storage.beginTx(); ContractBean contract = storage.getContract(contractId); if (contract == null) throw ExceptionFactory.contractNotFoundException(contractId); storage.commitTx(); // Hide some data if the user doesn't have the appView permission if (!hasPermission) { contract.setApikey(null); } log.debug(String.format("Got contract %s: %s", contract.getId(), contract)); //$NON-NLS-1$ return contract; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#deleteAllContracts(java.lang.String, java.lang.String, java.lang.String) */ @Override public void deleteAllContracts(String organizationId, String applicationId, String version) throws ApplicationNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); List<ContractSummaryBean> contracts = getApplicationVersionContracts(organizationId, applicationId, version); for (ContractSummaryBean contract : contracts) { deleteContract(organizationId, applicationId, version, contract.getContractId()); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#deleteContract(java.lang.String, java.lang.String, java.lang.String, java.lang.Long) */ @Override public void deleteContract(String organizationId, String applicationId, String version, Long contractId) throws ApplicationNotFoundException, ContractNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); try { storage.beginTx(); ContractBean contract = storage.getContract(contractId); if (contract == null) { throw ExceptionFactory.contractNotFoundException(contractId); } if (!contract.getApplication().getApplication().getOrganization().getId().equals(organizationId)) { throw ExceptionFactory.contractNotFoundException(contractId); } if (!contract.getApplication().getApplication().getId().equals(applicationId)) { throw ExceptionFactory.contractNotFoundException(contractId); } if (!contract.getApplication().getVersion().equals(version)) { throw ExceptionFactory.contractNotFoundException(contractId); } storage.deleteContract(contract); storage.createAuditEntry(AuditUtils.contractBrokenFromApp(contract, securityContext)); storage.createAuditEntry(AuditUtils.contractBrokenToService(contract, securityContext)); storage.commitTx(); log.debug(String.format("Deleted contract: %s", contract)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getApplicationVersionContracts(java.lang.String, java.lang.String, java.lang.String) */ @Override public List<ContractSummaryBean> getApplicationVersionContracts(String organizationId, String applicationId, String version) throws ApplicationNotFoundException, NotAuthorizedException { boolean hasPermission = securityContext.hasPermission(PermissionType.appView, organizationId); // Try to get the application first - will throw a ApplicationNotFoundException if not found. getAppVersion(organizationId, applicationId, version); try { List<ContractSummaryBean> contracts = query.getApplicationContracts(organizationId, applicationId, version); // Hide some stuff if the user doesn't have the appView permission if (!hasPermission) { for (ContractSummaryBean contract : contracts) { contract.setApikey(null); } } return contracts; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getApiRegistryJSON(java.lang.String, java.lang.String, java.lang.String) */ @Override public ApiRegistryBean getApiRegistryJSON(String organizationId, String applicationId, String version) throws ApplicationNotFoundException, NotAuthorizedException { return getApiRegistry(organizationId, applicationId, version); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getApiRegistryXML(java.lang.String, java.lang.String, java.lang.String) */ @Override public ApiRegistryBean getApiRegistryXML(String organizationId, String applicationId, String version) throws ApplicationNotFoundException, NotAuthorizedException { return getApiRegistry(organizationId, applicationId, version); } /** * Gets the API registry. * @param organizationId * @param applicationId * @param version * @throws ApplicationNotFoundException * @throws NotAuthorizedException */ protected ApiRegistryBean getApiRegistry(String organizationId, String applicationId, String version) throws ApplicationNotFoundException, NotAuthorizedException { boolean hasPermission = securityContext.hasPermission(PermissionType.appView, organizationId); // Try to get the application first - will throw a ApplicationNotFoundException if not found. getAppVersion(organizationId, applicationId, version); Map<String, IGatewayLink> gatewayLinks = new HashMap<>(); Map<String, GatewayBean> gateways = new HashMap<>(); boolean txStarted = false; try { ApiRegistryBean apiRegistry = query.getApiRegistry(organizationId, applicationId, version); // Hide some stuff if the user doesn't have the appView permission if (!hasPermission) { List<ApiEntryBean> apis = apiRegistry.getApis(); for (ApiEntryBean api : apis) { api.setApiKey(null); } } List<ApiEntryBean> apis = apiRegistry.getApis(); storage.beginTx(); txStarted = true; for (ApiEntryBean api : apis) { String gatewayId = api.getGatewayId(); // Don't return the gateway id. api.setGatewayId(null); GatewayBean gateway = gateways.get(gatewayId); if (gateway == null) { gateway = storage.getGateway(gatewayId); gateways.put(gatewayId, gateway); } IGatewayLink link = gatewayLinks.get(gatewayId); if (link == null) { link = gatewayLinkFactory.create(gateway); gatewayLinks.put(gatewayId, link); } ServiceEndpoint se = link.getServiceEndpoint(api.getServiceOrgId(), api.getServiceId(), api.getServiceVersion()); String apiEndpoint = se.getEndpoint(); api.setHttpEndpoint(apiEndpoint); } return apiRegistry; } catch (StorageException | GatewayAuthenticationException e) { throw new SystemErrorException(e); } finally { if (txStarted) { storage.rollbackTx(); } for (IGatewayLink link : gatewayLinks.values()) { link.close(); } } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createAppPolicy(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.policies.NewPolicyBean) */ @Override public PolicyBean createAppPolicy(String organizationId, String applicationId, String version, NewPolicyBean bean) throws OrganizationNotFoundException, ApplicationVersionNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the app version exists and is in the right state. ApplicationVersionBean avb = getAppVersion(organizationId, applicationId, version); if (avb.getStatus() == ApplicationStatus.Registered || avb.getStatus() == ApplicationStatus.Retired) { throw ExceptionFactory.invalidApplicationStatusException(); } return doCreatePolicy(organizationId, applicationId, version, bean, PolicyType.Application); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getAppPolicy(java.lang.String, java.lang.String, java.lang.String, long) */ @Override public PolicyBean getAppPolicy(String organizationId, String applicationId, String version, long policyId) throws OrganizationNotFoundException, ApplicationVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { boolean hasPermission = securityContext.hasPermission(PermissionType.appView, organizationId); // Make sure the app version exists getAppVersion(organizationId, applicationId, version); PolicyBean policy = doGetPolicy(PolicyType.Application, organizationId, applicationId, version, policyId); if (!hasPermission) { policy.setConfiguration(null); } return policy; } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#updateAppPolicy(java.lang.String, java.lang.String, java.lang.String, long, io.apiman.manager.api.beans.policies.UpdatePolicyBean) */ @Override public void updateAppPolicy(String organizationId, String applicationId, String version, long policyId, UpdatePolicyBean bean) throws OrganizationNotFoundException, ApplicationVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the app version exists. getAppVersion(organizationId, applicationId, version); try { storage.beginTx(); PolicyBean policy = this.storage.getPolicy(PolicyType.Application, organizationId, applicationId, version, policyId); if (policy == null) { throw ExceptionFactory.policyNotFoundException(policyId); } if (AuditUtils.valueChanged(policy.getConfiguration(), bean.getConfiguration())) { policy.setConfiguration(bean.getConfiguration()); // TODO figure out what changed an include that in the audit entry } policy.setModifiedOn(new Date()); policy.setModifiedBy(this.securityContext.getCurrentUser()); storage.updatePolicy(policy); storage.createAuditEntry(AuditUtils.policyUpdated(policy, PolicyType.Application, securityContext)); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#deleteAppPolicy(java.lang.String, java.lang.String, java.lang.String, long) */ @Override public void deleteAppPolicy(String organizationId, String applicationId, String version, long policyId) throws OrganizationNotFoundException, ApplicationVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the app version exists; ApplicationVersionBean app = getAppVersion(organizationId, applicationId, version); if (app.getStatus() == ApplicationStatus.Registered || app.getStatus() == ApplicationStatus.Retired) { throw ExceptionFactory.invalidApplicationStatusException(); } try { storage.beginTx(); PolicyBean policy = this.storage.getPolicy(PolicyType.Application, organizationId, applicationId, version, policyId); if (policy == null) { throw ExceptionFactory.policyNotFoundException(policyId); } storage.deletePolicy(policy); storage.createAuditEntry(AuditUtils.policyRemoved(policy, PolicyType.Application, securityContext)); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listAppPolicies(java.lang.String, java.lang.String, java.lang.String) */ @Override public List<PolicySummaryBean> listAppPolicies(String organizationId, String applicationId, String version) throws OrganizationNotFoundException, ApplicationVersionNotFoundException, NotAuthorizedException { // Try to get the application first - will throw an exception if not found. getAppVersion(organizationId, applicationId, version); try { return query.getPolicies(organizationId, applicationId, version, PolicyType.Application); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#reorderApplicationPolicies(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.policies.PolicyChainBean) */ @Override public void reorderApplicationPolicies(String organizationId, String applicationId, String version, PolicyChainBean policyChain) throws OrganizationNotFoundException, ApplicationVersionNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.appEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the app version exists. ApplicationVersionBean avb = getAppVersion(organizationId, applicationId, version); try { storage.beginTx(); List<Long> newOrder = new ArrayList<>(policyChain.getPolicies().size()); for (PolicySummaryBean psb : policyChain.getPolicies()) { newOrder.add(psb.getId()); } storage.reorderPolicies(PolicyType.Application, organizationId, applicationId, version, newOrder); storage.createAuditEntry(AuditUtils.policiesReordered(avb, PolicyType.Application, securityContext)); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createService(java.lang.String, io.apiman.manager.api.beans.services.NewServiceBean) */ @Override public ServiceBean createService(String organizationId, NewServiceBean bean) throws OrganizationNotFoundException, ServiceAlreadyExistsException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); ServiceBean newService = new ServiceBean(); newService.setName(bean.getName()); newService.setDescription(bean.getDescription()); newService.setId(BeanUtils.idFromName(bean.getName())); newService.setCreatedOn(new Date()); newService.setCreatedBy(securityContext.getCurrentUser()); try { GatewaySummaryBean gateway = getSingularGateway(); storage.beginTx(); OrganizationBean orgBean = storage.getOrganization(organizationId); if (orgBean == null) { throw ExceptionFactory.organizationNotFoundException(organizationId); } if (storage.getService(orgBean.getId(), newService.getId()) != null) { throw ExceptionFactory.serviceAlreadyExistsException(bean.getName()); } newService.setOrganization(orgBean); // Store/persist the new service storage.createService(newService); storage.createAuditEntry(AuditUtils.serviceCreated(newService, securityContext)); if (bean.getInitialVersion() != null) { NewServiceVersionBean newServiceVersion = new NewServiceVersionBean(); newServiceVersion.setVersion(bean.getInitialVersion()); createServiceVersionInternal(newServiceVersion, newService, gateway); } storage.commitTx(); return newService; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getService(java.lang.String, java.lang.String) */ @Override public ServiceBean getService(String organizationId, String serviceId) throws ServiceNotFoundException, NotAuthorizedException { try { storage.beginTx(); ServiceBean bean = storage.getService(organizationId, serviceId); if (bean == null) { throw ExceptionFactory.serviceNotFoundException(serviceId); } storage.commitTx(); return bean; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServiceActivity(java.lang.String, java.lang.String, int, int) */ @Override public SearchResultsBean<AuditEntryBean> getServiceActivity(String organizationId, String serviceId, int page, int pageSize) throws ServiceNotFoundException, NotAuthorizedException { if (page <= 1) { page = 1; } if (pageSize == 0) { pageSize = 20; } try { SearchResultsBean<AuditEntryBean> rval = null; PagingBean paging = new PagingBean(); paging.setPage(page); paging.setPageSize(pageSize); rval = query.auditEntity(organizationId, serviceId, null, ServiceBean.class, paging); return rval; } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listServices(java.lang.String) */ @Override public List<ServiceSummaryBean> listServices(String organizationId) throws OrganizationNotFoundException, NotAuthorizedException { // make sure the org exists get(organizationId); try { return query.getServicesInOrg(organizationId); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#updateService(java.lang.String, java.lang.String, io.apiman.manager.api.beans.services.UpdateServiceBean) */ @Override public void updateService(String organizationId, String serviceId, UpdateServiceBean bean) throws ServiceNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); try { storage.beginTx(); ServiceBean serviceForUpdate = storage.getService(organizationId, serviceId); if (serviceForUpdate == null) { throw ExceptionFactory.serviceNotFoundException(serviceId); } EntityUpdatedData auditData = new EntityUpdatedData(); if (AuditUtils.valueChanged(serviceForUpdate.getDescription(), bean.getDescription())) { auditData.addChange("description", serviceForUpdate.getDescription(), bean.getDescription()); //$NON-NLS-1$ serviceForUpdate.setDescription(bean.getDescription()); } storage.updateService(serviceForUpdate); storage.createAuditEntry(AuditUtils.serviceUpdated(serviceForUpdate, auditData, securityContext)); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createServiceVersion(java.lang.String, java.lang.String, io.apiman.manager.api.beans.services.NewServiceVersionBean) */ @Override public ServiceVersionBean createServiceVersion(String organizationId, String serviceId, NewServiceVersionBean bean) throws ServiceNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); ServiceVersionBean newVersion = null; try { GatewaySummaryBean gateway = getSingularGateway(); storage.beginTx(); ServiceBean service = storage.getService(organizationId, serviceId); if (service == null) { throw ExceptionFactory.serviceNotFoundException(serviceId); } newVersion = createServiceVersionInternal(bean, service, gateway); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } if (bean.isClone() && bean.getCloneVersion() != null) { try { ServiceVersionBean cloneSource = getServiceVersion(organizationId, serviceId, bean.getCloneVersion()); // Clone primary attributes of the service version UpdateServiceVersionBean updatedService = new UpdateServiceVersionBean(); updatedService.setEndpoint(cloneSource.getEndpoint()); updatedService.setEndpointType(cloneSource.getEndpointType()); updatedService.setEndpointProperties(cloneSource.getEndpointProperties()); updatedService.setGateways(cloneSource.getGateways()); updatedService.setPlans(cloneSource.getPlans()); updatedService.setPublicService(cloneSource.isPublicService()); newVersion = updateServiceVersion(organizationId, serviceId, bean.getVersion(), updatedService); // Clone the service definition document try { Response response = getServiceDefinition(organizationId, serviceId, bean.getCloneVersion()); InputStream definition = (InputStream) response.getEntity(); storeServiceDefinition(organizationId, serviceId, newVersion.getVersion(), cloneSource.getDefinitionType(), definition); } catch (ServiceDefinitionNotFoundException svnfe) { // This is ok - it just means the service doesn't have one, so do nothing. } catch (Exception sdnfe) { log.error("Unable to create response", sdnfe); //$NON-NLS-1$ } // Clone all service policies List<PolicySummaryBean> policies = listServicePolicies(organizationId, serviceId, bean.getCloneVersion()); for (PolicySummaryBean policySummary : policies) { PolicyBean policy = getServicePolicy(organizationId, serviceId, bean.getCloneVersion(), policySummary.getId()); NewPolicyBean npb = new NewPolicyBean(); npb.setDefinitionId(policy.getDefinition().getId()); npb.setConfiguration(policy.getConfiguration()); createServicePolicy(organizationId, serviceId, newVersion.getVersion(), npb); } } catch (Exception e) { // TODO it's ok if the clone fails - we did our best if (e != null) { Throwable t = e; e = (Exception) t; } } } return newVersion; } /** * Creates a service version. * @param bean * @param service * @param gateway * @throws Exception * @throws StorageException */ protected ServiceVersionBean createServiceVersionInternal(NewServiceVersionBean bean, ServiceBean service, GatewaySummaryBean gateway) throws Exception, StorageException { if (!BeanUtils.isValidVersion(bean.getVersion())) { throw new StorageException("Invalid/illegal service version: " + bean.getVersion()); //$NON-NLS-1$ } ServiceVersionBean newVersion = new ServiceVersionBean(); newVersion.setVersion(bean.getVersion()); newVersion.setCreatedBy(securityContext.getCurrentUser()); newVersion.setCreatedOn(new Date()); newVersion.setModifiedBy(securityContext.getCurrentUser()); newVersion.setModifiedOn(new Date()); newVersion.setStatus(ServiceStatus.Created); newVersion.setService(service); if (gateway != null) { if (newVersion.getGateways() == null) { newVersion.setGateways(new HashSet<ServiceGatewayBean>()); ServiceGatewayBean sgb = new ServiceGatewayBean(); sgb.setGatewayId(gateway.getId()); newVersion.getGateways().add(sgb); } } if (serviceValidator.isReady(newVersion)) { newVersion.setStatus(ServiceStatus.Ready); } else { newVersion.setStatus(ServiceStatus.Created); } // Ensure all of the plans are in the right status (locked) Set<ServicePlanBean> plans = newVersion.getPlans(); if (plans != null) { for (ServicePlanBean splanBean : plans) { String orgId = newVersion.getService().getOrganization().getId(); PlanVersionBean pvb = storage.getPlanVersion(orgId, splanBean.getPlanId(), splanBean.getVersion()); if (pvb == null) { throw new StorageException(Messages.i18n.format("PlanVersionDoesNotExist", //$NON-NLS-1$ splanBean.getPlanId(), splanBean.getVersion())); } if (pvb.getStatus() != PlanStatus.Locked) { throw new StorageException( Messages.i18n.format("PlanNotLocked", splanBean.getPlanId(), splanBean.getVersion())); //$NON-NLS-1$ } } } storage.createServiceVersion(newVersion); storage.createAuditEntry(AuditUtils.serviceVersionCreated(newVersion, securityContext)); return newVersion; } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServiceVersion(java.lang.String, java.lang.String, java.lang.String) */ @Override public ServiceVersionBean getServiceVersion(String organizationId, String serviceId, String version) throws ServiceVersionNotFoundException, NotAuthorizedException { boolean hasPermission = securityContext.hasPermission(PermissionType.svcView, organizationId); try { storage.beginTx(); ServiceVersionBean serviceVersion = storage.getServiceVersion(organizationId, serviceId, version); if (serviceVersion == null) { throw ExceptionFactory.serviceVersionNotFoundException(serviceId, version); } storage.commitTx(); if (!hasPermission) { serviceVersion.setGateways(null); } decryptEndpointProperties(serviceVersion); return serviceVersion; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServiceDefinition(java.lang.String, java.lang.String, java.lang.String) */ @Override public Response getServiceDefinition(String organizationId, String serviceId, String version) throws ServiceVersionNotFoundException, NotAuthorizedException { try { storage.beginTx(); ServiceVersionBean serviceVersion = storage.getServiceVersion(organizationId, serviceId, version); if (serviceVersion == null) { throw ExceptionFactory.serviceVersionNotFoundException(serviceId, version); } if (serviceVersion.getDefinitionType() == ServiceDefinitionType.None || serviceVersion.getDefinitionType() == null) { throw ExceptionFactory.serviceDefinitionNotFoundException(serviceId, version); } InputStream definition = storage.getServiceDefinition(serviceVersion); if (definition == null) { throw ExceptionFactory.serviceDefinitionNotFoundException(serviceId, version); } ResponseBuilder builder = Response.ok().entity(definition); if (serviceVersion.getDefinitionType() == ServiceDefinitionType.SwaggerJSON) { builder.type(MediaType.APPLICATION_JSON); } else if (serviceVersion.getDefinitionType() == ServiceDefinitionType.SwaggerYAML) { builder.type("application/x-yaml"); //$NON-NLS-1$ } else if (serviceVersion.getDefinitionType() == ServiceDefinitionType.WSDL) { builder.type("application/wsdl+xml"); //$NON-NLS-1$ } else { throw new Exception("Service definition type not supported: " + serviceVersion.getDefinitionType()); //$NON-NLS-1$ } storage.commitTx(); return builder.build(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServiceVersionEndpointInfo(java.lang.String, java.lang.String, java.lang.String) */ @Override public ServiceVersionEndpointSummaryBean getServiceVersionEndpointInfo(String organizationId, String serviceId, String version) throws ServiceVersionNotFoundException, InvalidServiceStatusException, GatewayNotFoundException { try { storage.beginTx(); ServiceVersionBean serviceVersion = storage.getServiceVersion(organizationId, serviceId, version); if (serviceVersion == null) { throw ExceptionFactory.serviceVersionNotFoundException(serviceId, version); } if (serviceVersion.getStatus() != ServiceStatus.Published) { throw new InvalidServiceStatusException(Messages.i18n.format("ServiceNotPublished")); //$NON-NLS-1$ } Set<ServiceGatewayBean> gateways = serviceVersion.getGateways(); if (gateways.isEmpty()) { throw new SystemErrorException("No Gateways for published Service!"); //$NON-NLS-1$ } GatewayBean gateway = storage.getGateway(gateways.iterator().next().getGatewayId()); if (gateway == null) { throw new GatewayNotFoundException(); } IGatewayLink link = gatewayLinkFactory.create(gateway); ServiceEndpoint endpoint = link.getServiceEndpoint(organizationId, serviceId, version); ServiceVersionEndpointSummaryBean rval = new ServiceVersionEndpointSummaryBean(); rval.setManagedEndpoint(endpoint.getEndpoint()); storage.commitTx(); log.debug(String.format("Got endpoint summary: %s", gateway)); //$NON-NLS-1$ return rval; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServiceVersionActivity(java.lang.String, java.lang.String, java.lang.String, int, int) */ @Override public SearchResultsBean<AuditEntryBean> getServiceVersionActivity(String organizationId, String serviceId, String version, int page, int pageSize) throws ServiceVersionNotFoundException, NotAuthorizedException { if (page <= 1) { page = 1; } if (pageSize == 0) { pageSize = 20; } try { SearchResultsBean<AuditEntryBean> rval = null; PagingBean paging = new PagingBean(); paging.setPage(page); paging.setPageSize(pageSize); rval = query.auditEntity(organizationId, serviceId, version, ServiceBean.class, paging); return rval; } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#updateServiceVersion(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.services.UpdateServiceVersionBean) */ @Override public ServiceVersionBean updateServiceVersion(String organizationId, String serviceId, String version, UpdateServiceVersionBean bean) throws ServiceVersionNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); ServiceVersionBean svb = getServiceVersion(organizationId, serviceId, version); if (svb.getStatus() == ServiceStatus.Published || svb.getStatus() == ServiceStatus.Retired) { throw ExceptionFactory.invalidServiceStatusException(); } svb.setModifiedBy(securityContext.getCurrentUser()); svb.setModifiedOn(new Date()); EntityUpdatedData data = new EntityUpdatedData(); if (AuditUtils.valueChanged(svb.getPlans(), bean.getPlans())) { data.addChange("plans", AuditUtils.asString_ServicePlanBeans(svb.getPlans()), //$NON-NLS-1$ AuditUtils.asString_ServicePlanBeans(bean.getPlans())); if (svb.getPlans() == null) { svb.setPlans(new HashSet<ServicePlanBean>()); } svb.getPlans().clear(); if (bean.getPlans() != null) { svb.getPlans().addAll(bean.getPlans()); } } if (AuditUtils.valueChanged(svb.getGateways(), bean.getGateways())) { data.addChange("gateways", AuditUtils.asString_ServiceGatewayBeans(svb.getGateways()), //$NON-NLS-1$ AuditUtils.asString_ServiceGatewayBeans(bean.getGateways())); if (svb.getGateways() == null) { svb.setGateways(new HashSet<ServiceGatewayBean>()); } svb.getGateways().clear(); svb.getGateways().addAll(bean.getGateways()); } if (AuditUtils.valueChanged(svb.getEndpoint(), bean.getEndpoint())) { data.addChange("endpoint", svb.getEndpoint(), bean.getEndpoint()); //$NON-NLS-1$ svb.setEndpoint(bean.getEndpoint()); } if (AuditUtils.valueChanged(svb.getEndpointType(), bean.getEndpointType())) { data.addChange("endpointType", svb.getEndpointType(), bean.getEndpointType()); //$NON-NLS-1$ svb.setEndpointType(bean.getEndpointType()); } if (AuditUtils.valueChanged(svb.getEndpointProperties(), bean.getEndpointProperties())) { if (svb.getEndpointProperties() == null) { svb.setEndpointProperties(new HashMap<String, String>()); } else { svb.getEndpointProperties().clear(); } if (bean.getEndpointProperties() != null) { svb.getEndpointProperties().putAll(bean.getEndpointProperties()); } } if (AuditUtils.valueChanged(svb.isPublicService(), bean.getPublicService())) { data.addChange("publicService", String.valueOf(svb.isPublicService()), //$NON-NLS-1$ String.valueOf(bean.getPublicService())); svb.setPublicService(bean.getPublicService()); } try { if (svb.getGateways() == null || svb.getGateways().isEmpty()) { GatewaySummaryBean gateway = getSingularGateway(); if (gateway != null) { if (svb.getGateways() == null) { svb.setGateways(new HashSet<ServiceGatewayBean>()); ServiceGatewayBean sgb = new ServiceGatewayBean(); sgb.setGatewayId(gateway.getId()); svb.getGateways().add(sgb); } } } if (serviceValidator.isReady(svb)) { svb.setStatus(ServiceStatus.Ready); } else { svb.setStatus(ServiceStatus.Created); } } catch (Exception e) { throw new SystemErrorException(e); } try { encryptEndpointProperties(svb); storage.beginTx(); // Ensure all of the plans are in the right status (locked) Set<ServicePlanBean> plans = svb.getPlans(); if (plans != null) { for (ServicePlanBean splanBean : plans) { String orgId = svb.getService().getOrganization().getId(); PlanVersionBean pvb = storage.getPlanVersion(orgId, splanBean.getPlanId(), splanBean.getVersion()); if (pvb == null) { throw new StorageException(Messages.i18n.format("PlanVersionDoesNotExist", //$NON-NLS-1$ splanBean.getPlanId(), splanBean.getVersion())); } if (pvb.getStatus() != PlanStatus.Locked) { throw new StorageException(Messages.i18n.format("PlanNotLocked", splanBean.getPlanId(), //$NON-NLS-1$ splanBean.getVersion())); } } } storage.updateServiceVersion(svb); storage.createAuditEntry(AuditUtils.serviceVersionUpdated(svb, data, securityContext)); storage.commitTx(); log.debug(String.format("Successfully updated Service Version: %s", svb)); //$NON-NLS-1$ decryptEndpointProperties(svb); return svb; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#updateServiceDefinition(java.lang.String, java.lang.String, java.lang.String) */ @Override public void updateServiceDefinition(String organizationId, String serviceId, String version) throws ServiceVersionNotFoundException, NotAuthorizedException, InvalidServiceStatusException { String contentType = request.getContentType(); InputStream data; try { data = request.getInputStream(); } catch (IOException e) { throw new SystemErrorException(e); } ServiceDefinitionType newDefinitionType = null; if (contentType.toLowerCase().contains("application/json")) { //$NON-NLS-1$ newDefinitionType = ServiceDefinitionType.SwaggerJSON; } else if (contentType.toLowerCase().contains("application/x-yaml")) { //$NON-NLS-1$ newDefinitionType = ServiceDefinitionType.SwaggerYAML; } else if (contentType.toLowerCase().contains("application/wsdl+xml")) { //$NON-NLS-1$ newDefinitionType = ServiceDefinitionType.WSDL; } else { throw new SystemErrorException( Messages.i18n.format("InvalidServiceDefinitionContentType", contentType)); //$NON-NLS-1$ } storeServiceDefinition(organizationId, serviceId, version, newDefinitionType, data); log.debug(String.format("Updated service definition for %s", serviceId)); //$NON-NLS-1$ } /** * @param organizationId * @param serviceId * @param version * @param contentType * @param data */ protected void storeServiceDefinition(String organizationId, String serviceId, String version, ServiceDefinitionType definitionType, InputStream data) { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); try { storage.beginTx(); ServiceVersionBean serviceVersion = storage.getServiceVersion(organizationId, serviceId, version); if (serviceVersion == null) { throw ExceptionFactory.serviceVersionNotFoundException(serviceId, version); } if (serviceVersion.getDefinitionType() != definitionType) { serviceVersion.setDefinitionType(definitionType); storage.updateServiceVersion(serviceVersion); } storage.createAuditEntry(AuditUtils.serviceDefinitionUpdated(serviceVersion, securityContext)); storage.updateServiceDefinition(serviceVersion, data); storage.commitTx(); log.debug(String.format("Stored service definition %s: %s", serviceId, serviceVersion)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listServiceVersions(java.lang.String, java.lang.String) */ @Override public List<ServiceVersionSummaryBean> listServiceVersions(String organizationId, String serviceId) throws ServiceNotFoundException, NotAuthorizedException { // Try to get the service first - will throw a ServiceNotFoundException if not found. getService(organizationId, serviceId); try { return query.getServiceVersions(organizationId, serviceId); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServiceVersionPlans(java.lang.String, java.lang.String, java.lang.String) */ @Override public List<ServicePlanSummaryBean> getServiceVersionPlans(String organizationId, String serviceId, String version) throws ServiceVersionNotFoundException, NotAuthorizedException { // Ensure the version exists first. getServiceVersion(organizationId, serviceId, version); try { return query.getServiceVersionPlans(organizationId, serviceId, version); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createServicePolicy(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.policies.NewPolicyBean) */ @Override public PolicyBean createServicePolicy(String organizationId, String serviceId, String version, NewPolicyBean bean) throws OrganizationNotFoundException, ServiceVersionNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the service exists ServiceVersionBean svb = getServiceVersion(organizationId, serviceId, version); if (svb.getStatus() == ServiceStatus.Published || svb.getStatus() == ServiceStatus.Retired) { throw ExceptionFactory.invalidServiceStatusException(); } log.debug(String.format("Created service policy %s", svb)); //$NON-NLS-1$ return doCreatePolicy(organizationId, serviceId, version, bean, PolicyType.Service); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServicePolicy(java.lang.String, java.lang.String, java.lang.String, long) */ @Override public PolicyBean getServicePolicy(String organizationId, String serviceId, String version, long policyId) throws OrganizationNotFoundException, ServiceVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { // Make sure the service exists getServiceVersion(organizationId, serviceId, version); PolicyBean policy = doGetPolicy(PolicyType.Service, organizationId, serviceId, version, policyId); if (!securityContext.hasPermission(PermissionType.svcView, organizationId)) { policy.setConfiguration(null); } return policy; } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#updateServicePolicy(java.lang.String, * java.lang.String, java.lang.String, long, io.apiman.manager.api.beans.policies.UpdatePolicyBean) */ @Override public void updateServicePolicy(String organizationId, String serviceId, String version, long policyId, UpdatePolicyBean bean) throws OrganizationNotFoundException, ServiceVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the service exists getServiceVersion(organizationId, serviceId, version); try { storage.beginTx(); PolicyBean policy = storage.getPolicy(PolicyType.Service, organizationId, serviceId, version, policyId); if (policy == null) { throw ExceptionFactory.policyNotFoundException(policyId); } // TODO capture specific change values when auditing policy updates if (AuditUtils.valueChanged(policy.getConfiguration(), bean.getConfiguration())) { policy.setConfiguration(bean.getConfiguration()); } policy.setModifiedOn(new Date()); policy.setModifiedBy(securityContext.getCurrentUser()); storage.updatePolicy(policy); storage.createAuditEntry(AuditUtils.policyUpdated(policy, PolicyType.Service, securityContext)); storage.commitTx(); log.debug(String.format("Updated service policy %s", policy)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#deleteServicePolicy(java.lang.String, java.lang.String, java.lang.String, long) */ @Override public void deleteServicePolicy(String organizationId, String serviceId, String version, long policyId) throws OrganizationNotFoundException, ServiceVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the service exists ServiceVersionBean service = getServiceVersion(organizationId, serviceId, version); if (service.getStatus() == ServiceStatus.Published || service.getStatus() == ServiceStatus.Retired) { throw ExceptionFactory.invalidServiceStatusException(); } try { storage.beginTx(); PolicyBean policy = this.storage.getPolicy(PolicyType.Service, organizationId, serviceId, version, policyId); if (policy == null) { throw ExceptionFactory.policyNotFoundException(policyId); } storage.deletePolicy(policy); storage.createAuditEntry(AuditUtils.policyRemoved(policy, PolicyType.Service, securityContext)); storage.commitTx(); log.debug(String.format("Deleted service %s policy: %s", serviceId, policy)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#deleteServiceDefinition(java.lang.String, java.lang.String, java.lang.String) */ @Override public void deleteServiceDefinition(String organizationId, String serviceId, String version) throws OrganizationNotFoundException, ServiceVersionNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); try { storage.beginTx(); ServiceVersionBean serviceVersion = storage.getServiceVersion(organizationId, serviceId, version); if (serviceVersion == null) { throw ExceptionFactory.serviceVersionNotFoundException(serviceId, version); } serviceVersion.setDefinitionType(ServiceDefinitionType.None); storage.createAuditEntry(AuditUtils.serviceDefinitionDeleted(serviceVersion, securityContext)); storage.deleteServiceDefinition(serviceVersion); storage.updateServiceVersion(serviceVersion); storage.commitTx(); log.debug(String.format("Deleted service %s definition %s", serviceId, serviceVersion)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listServicePolicies(java.lang.String, java.lang.String, java.lang.String) */ @Override public List<PolicySummaryBean> listServicePolicies(String organizationId, String serviceId, String version) throws OrganizationNotFoundException, ServiceVersionNotFoundException, NotAuthorizedException { // Try to get the service first - will throw an exception if not found. getServiceVersion(organizationId, serviceId, version); try { return query.getPolicies(organizationId, serviceId, version, PolicyType.Service); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#reorderServicePolicies(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.policies.PolicyChainBean) */ @Override public void reorderServicePolicies(String organizationId, String serviceId, String version, PolicyChainBean policyChain) throws OrganizationNotFoundException, ServiceVersionNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.svcEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the service exists ServiceVersionBean svb = getServiceVersion(organizationId, serviceId, version); try { storage.beginTx(); List<Long> newOrder = new ArrayList<>(policyChain.getPolicies().size()); for (PolicySummaryBean psb : policyChain.getPolicies()) { newOrder.add(psb.getId()); } storage.reorderPolicies(PolicyType.Service, organizationId, serviceId, version, newOrder); storage.createAuditEntry(AuditUtils.policiesReordered(svb, PolicyType.Service, securityContext)); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServicePolicyChain(java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override public PolicyChainBean getServicePolicyChain(String organizationId, String serviceId, String version, String planId) throws ServiceVersionNotFoundException, PlanNotFoundException, NotAuthorizedException { // Try to get the service first - will throw an exception if not found. ServiceVersionBean svb = getServiceVersion(organizationId, serviceId, version); try { String planVersion = null; Set<ServicePlanBean> plans = svb.getPlans(); if (plans != null) { for (ServicePlanBean servicePlanBean : plans) { if (servicePlanBean.getPlanId().equals(planId)) { planVersion = servicePlanBean.getVersion(); break; } } } if (planVersion == null) { throw ExceptionFactory.planNotFoundException(planId); } List<PolicySummaryBean> servicePolicies = query.getPolicies(organizationId, serviceId, version, PolicyType.Service); List<PolicySummaryBean> planPolicies = query.getPolicies(organizationId, planId, planVersion, PolicyType.Plan); PolicyChainBean chain = new PolicyChainBean(); chain.getPolicies().addAll(planPolicies); chain.getPolicies().addAll(servicePolicies); return chain; } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getServiceVersionContracts(java.lang.String, java.lang.String, java.lang.String, int, int) */ @Override public List<ContractSummaryBean> getServiceVersionContracts(String organizationId, String serviceId, String version, int page, int pageSize) throws ServiceVersionNotFoundException, NotAuthorizedException { if (page <= 1) { page = 1; } if (pageSize == 0) { pageSize = 20; } // Try to get the service first - will throw an exception if not found. getServiceVersion(organizationId, serviceId, version); try { List<ContractSummaryBean> contracts = query.getServiceContracts(organizationId, serviceId, version, page, pageSize); for (ContractSummaryBean contract : contracts) { if (!securityContext.hasPermission(PermissionType.appView, contract.getAppOrganizationId())) { contract.setApikey(null); } } log.debug(String.format("Got service %s version %s contracts: %s", serviceId, version, contracts)); //$NON-NLS-1$ return contracts; } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getUsage(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.metrics.HistogramIntervalType, java.lang.String, java.lang.String) */ @Override public UsageHistogramBean getUsage(String organizationId, String serviceId, String version, HistogramIntervalType interval, String fromDate, String toDate) throws NotAuthorizedException, InvalidMetricCriteriaException { if (!securityContext.hasPermission(PermissionType.svcView, organizationId)) throw ExceptionFactory.notAuthorizedException(); DateTime from = parseFromDate(fromDate); DateTime to = parseToDate(toDate); if (interval == null) { interval = HistogramIntervalType.day; } validateMetricRange(from, to); validateTimeSeriesMetric(from, to, interval); return metrics.getUsage(organizationId, serviceId, version, interval, from, to); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getUsagePerApp(java.lang.String, java.lang.String, java.lang.String, java.util.Date, java.util.Date) */ @Override public UsagePerAppBean getUsagePerApp(String organizationId, String serviceId, String version, String fromDate, String toDate) throws NotAuthorizedException, InvalidMetricCriteriaException { if (!securityContext.hasPermission(PermissionType.svcView, organizationId)) throw ExceptionFactory.notAuthorizedException(); DateTime from = parseFromDate(fromDate); DateTime to = parseToDate(toDate); validateMetricRange(from, to); return metrics.getUsagePerApp(organizationId, serviceId, version, from, to); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getUsagePerPlan(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override public UsagePerPlanBean getUsagePerPlan(String organizationId, String serviceId, String version, String fromDate, String toDate) throws NotAuthorizedException, InvalidMetricCriteriaException { if (!securityContext.hasPermission(PermissionType.svcView, organizationId)) throw ExceptionFactory.notAuthorizedException(); DateTime from = parseFromDate(fromDate); DateTime to = parseToDate(toDate); validateMetricRange(from, to); return metrics.getUsagePerPlan(organizationId, serviceId, version, from, to); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getResponseStats(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.metrics.HistogramIntervalType, java.lang.String, java.lang.String) */ @Override public ResponseStatsHistogramBean getResponseStats(String organizationId, String serviceId, String version, HistogramIntervalType interval, String fromDate, String toDate) throws NotAuthorizedException, InvalidMetricCriteriaException { if (!securityContext.hasPermission(PermissionType.svcView, organizationId)) throw ExceptionFactory.notAuthorizedException(); DateTime from = parseFromDate(fromDate); DateTime to = parseToDate(toDate); if (interval == null) { interval = HistogramIntervalType.day; } validateMetricRange(from, to); validateTimeSeriesMetric(from, to, interval); return metrics.getResponseStats(organizationId, serviceId, version, interval, from, to); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getResponseStatsSummary(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override public ResponseStatsSummaryBean getResponseStatsSummary(String organizationId, String serviceId, String version, String fromDate, String toDate) throws NotAuthorizedException, InvalidMetricCriteriaException { if (!securityContext.hasPermission(PermissionType.svcView, organizationId)) throw ExceptionFactory.notAuthorizedException(); DateTime from = parseFromDate(fromDate); DateTime to = parseToDate(toDate); validateMetricRange(from, to); return metrics.getResponseStatsSummary(organizationId, serviceId, version, from, to); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getResponseStatsPerApp(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override public ResponseStatsPerAppBean getResponseStatsPerApp(String organizationId, String serviceId, String version, String fromDate, String toDate) throws NotAuthorizedException, InvalidMetricCriteriaException { if (!securityContext.hasPermission(PermissionType.svcView, organizationId)) throw ExceptionFactory.notAuthorizedException(); DateTime from = parseFromDate(fromDate); DateTime to = parseToDate(toDate); validateMetricRange(from, to); return metrics.getResponseStatsPerApp(organizationId, serviceId, version, from, to); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getResponseStatsPerPlan(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override public ResponseStatsPerPlanBean getResponseStatsPerPlan(String organizationId, String serviceId, String version, String fromDate, String toDate) throws NotAuthorizedException, InvalidMetricCriteriaException { if (!securityContext.hasPermission(PermissionType.svcView, organizationId)) throw ExceptionFactory.notAuthorizedException(); DateTime from = parseFromDate(fromDate); DateTime to = parseToDate(toDate); validateMetricRange(from, to); return metrics.getResponseStatsPerPlan(organizationId, serviceId, version, from, to); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createPlan(java.lang.String, * io.apiman.manager.api.beans.plans.NewPlanBean) */ @Override public PlanBean createPlan(String organizationId, NewPlanBean bean) throws OrganizationNotFoundException, PlanAlreadyExistsException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.planEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); PlanBean newPlan = new PlanBean(); newPlan.setName(bean.getName()); newPlan.setDescription(bean.getDescription()); newPlan.setId(BeanUtils.idFromName(bean.getName())); newPlan.setCreatedOn(new Date()); newPlan.setCreatedBy(securityContext.getCurrentUser()); try { // Store/persist the new plan storage.beginTx(); OrganizationBean orgBean = storage.getOrganization(organizationId); if (orgBean == null) { throw ExceptionFactory.organizationNotFoundException(organizationId); } if (storage.getPlan(orgBean.getId(), newPlan.getId()) != null) { throw ExceptionFactory.planAlreadyExistsException(newPlan.getName()); } newPlan.setOrganization(orgBean); storage.createPlan(newPlan); storage.createAuditEntry(AuditUtils.planCreated(newPlan, securityContext)); if (bean.getInitialVersion() != null) { NewPlanVersionBean newPlanVersion = new NewPlanVersionBean(); newPlanVersion.setVersion(bean.getInitialVersion()); createPlanVersionInternal(newPlanVersion, newPlan); } storage.commitTx(); log.debug(String.format("Created plan: %s", newPlan)); //$NON-NLS-1$ return newPlan; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getPlan(java.lang.String, java.lang.String) */ @Override public PlanBean getPlan(String organizationId, String planId) throws PlanNotFoundException, NotAuthorizedException { try { storage.beginTx(); PlanBean bean = storage.getPlan(organizationId, planId); if (bean == null) { throw ExceptionFactory.planNotFoundException(planId); } storage.commitTx(); log.debug(String.format("Got plan: %s", bean)); //$NON-NLS-1$ return bean; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getPlanActivity(java.lang.String, java.lang.String, int, int) */ @Override public SearchResultsBean<AuditEntryBean> getPlanActivity(String organizationId, String planId, int page, int pageSize) throws PlanNotFoundException, NotAuthorizedException { if (page <= 1) { page = 1; } if (pageSize == 0) { pageSize = 20; } try { SearchResultsBean<AuditEntryBean> rval = null; PagingBean paging = new PagingBean(); paging.setPage(page); paging.setPageSize(pageSize); rval = query.auditEntity(organizationId, planId, null, PlanBean.class, paging); return rval; } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listPlans(java.lang.String) */ @Override public List<PlanSummaryBean> listPlans(String organizationId) throws OrganizationNotFoundException, NotAuthorizedException { get(organizationId); try { return query.getPlansInOrg(organizationId); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#updatePlan(java.lang.String, * java.lang.String, io.apiman.manager.api.beans.plans.UpdatePlanBean) */ @Override public void updatePlan(String organizationId, String planId, UpdatePlanBean bean) throws PlanNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.planEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); EntityUpdatedData auditData = new EntityUpdatedData(); try { storage.beginTx(); PlanBean planForUpdate = storage.getPlan(organizationId, planId); if (planForUpdate == null) { throw ExceptionFactory.planNotFoundException(planId); } if (AuditUtils.valueChanged(planForUpdate.getDescription(), bean.getDescription())) { auditData.addChange("description", planForUpdate.getDescription(), bean.getDescription()); //$NON-NLS-1$ planForUpdate.setDescription(bean.getDescription()); } storage.updatePlan(planForUpdate); storage.createAuditEntry(AuditUtils.planUpdated(planForUpdate, auditData, securityContext)); storage.commitTx(); log.debug(String.format("Updated plan: %s", planForUpdate)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createPlanVersion(java.lang.String, * java.lang.String, io.apiman.manager.api.beans.plans.NewPlanVersionBean) */ @Override public PlanVersionBean createPlanVersion(String organizationId, String planId, NewPlanVersionBean bean) throws PlanNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.planEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); PlanVersionBean newVersion = null; try { storage.beginTx(); PlanBean plan = storage.getPlan(organizationId, planId); if (plan == null) { throw ExceptionFactory.planNotFoundException(planId); } newVersion = createPlanVersionInternal(bean, plan); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } if (bean.isClone() && bean.getCloneVersion() != null) { try { List<PolicySummaryBean> policies = listPlanPolicies(organizationId, planId, bean.getCloneVersion()); for (PolicySummaryBean policySummary : policies) { PolicyBean policy = getPlanPolicy(organizationId, planId, bean.getCloneVersion(), policySummary.getId()); NewPolicyBean npb = new NewPolicyBean(); npb.setDefinitionId(policy.getDefinition().getId()); npb.setConfiguration(policy.getConfiguration()); createPlanPolicy(organizationId, planId, newVersion.getVersion(), npb); } } catch (Exception e) { // TODO it's ok if the clone fails - we did our best } } log.debug(String.format("Created plan %s version: %s", planId, newVersion)); //$NON-NLS-1$ return newVersion; } /** * Creates a plan version. * @param bean * @param plan * @throws StorageException */ protected PlanVersionBean createPlanVersionInternal(NewPlanVersionBean bean, PlanBean plan) throws StorageException { if (!BeanUtils.isValidVersion(bean.getVersion())) { throw new StorageException("Invalid/illegal plan version: " + bean.getVersion()); //$NON-NLS-1$ } PlanVersionBean newVersion = new PlanVersionBean(); newVersion.setCreatedBy(securityContext.getCurrentUser()); newVersion.setCreatedOn(new Date()); newVersion.setModifiedBy(securityContext.getCurrentUser()); newVersion.setModifiedOn(new Date()); newVersion.setStatus(PlanStatus.Created); newVersion.setPlan(plan); newVersion.setVersion(bean.getVersion()); storage.createPlanVersion(newVersion); storage.createAuditEntry(AuditUtils.planVersionCreated(newVersion, securityContext)); return newVersion; } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getPlanVersion(java.lang.String, java.lang.String, java.lang.String) */ @Override public PlanVersionBean getPlanVersion(String organizationId, String planId, String version) throws PlanVersionNotFoundException, NotAuthorizedException { try { storage.beginTx(); PlanVersionBean planVersion = storage.getPlanVersion(organizationId, planId, version); if (planVersion == null) { throw ExceptionFactory.planVersionNotFoundException(planId, version); } storage.commitTx(); log.debug(String.format("Got plan %s version: %s", planId, planVersion)); //$NON-NLS-1$ return planVersion; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getPlanVersionActivity(java.lang.String, java.lang.String, java.lang.String, int, int) */ @Override public SearchResultsBean<AuditEntryBean> getPlanVersionActivity(String organizationId, String planId, String version, int page, int pageSize) throws PlanVersionNotFoundException, NotAuthorizedException { if (page <= 1) { page = 1; } if (pageSize == 0) { pageSize = 20; } try { SearchResultsBean<AuditEntryBean> rval = null; PagingBean paging = new PagingBean(); paging.setPage(page); paging.setPageSize(pageSize); rval = query.auditEntity(organizationId, planId, version, PlanBean.class, paging); return rval; } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listPlanVersions(java.lang.String, java.lang.String) */ @Override public List<PlanVersionSummaryBean> listPlanVersions(String organizationId, String planId) throws PlanNotFoundException, NotAuthorizedException { // Try to get the plan first - will throw a PlanNotFoundException if not found. getPlan(organizationId, planId); try { return query.getPlanVersions(organizationId, planId); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#createPlanPolicy(java.lang.String, * java.lang.String, java.lang.String, io.apiman.manager.api.beans.policies.NewPolicyBean) */ @Override public PolicyBean createPlanPolicy(String organizationId, String planId, String version, NewPolicyBean bean) throws OrganizationNotFoundException, PlanVersionNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.planEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the plan version exists and is in the right state PlanVersionBean pvb = getPlanVersion(organizationId, planId, version); if (pvb.getStatus() == PlanStatus.Locked) { throw ExceptionFactory.invalidPlanStatusException(); } log.debug(String.format("Creating plan %s policy %s", planId, pvb)); //$NON-NLS-1$ return doCreatePolicy(organizationId, planId, version, bean, PolicyType.Plan); } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#getPlanPolicy(java.lang.String, java.lang.String, java.lang.String, long) */ @Override public PolicyBean getPlanPolicy(String organizationId, String planId, String version, long policyId) throws OrganizationNotFoundException, PlanVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { boolean hasPermission = securityContext.hasPermission(PermissionType.planView, organizationId); // Make sure the plan version exists getPlanVersion(organizationId, planId, version); PolicyBean policy = doGetPolicy(PolicyType.Plan, organizationId, planId, version, policyId); if (!hasPermission) { policy.setConfiguration(null); } log.debug(String.format("Got plan policy %s", policy)); //$NON-NLS-1$ return policy; } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#updatePlanPolicy(java.lang.String, * java.lang.String, java.lang.String, long, io.apiman.manager.api.beans.policies.UpdatePolicyBean) */ @Override public void updatePlanPolicy(String organizationId, String planId, String version, long policyId, UpdatePolicyBean bean) throws OrganizationNotFoundException, PlanVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.planEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the plan version exists getPlanVersion(organizationId, planId, version); try { storage.beginTx(); PolicyBean policy = storage.getPolicy(PolicyType.Plan, organizationId, planId, version, policyId); if (policy == null) { throw ExceptionFactory.policyNotFoundException(policyId); } if (AuditUtils.valueChanged(policy.getConfiguration(), bean.getConfiguration())) { policy.setConfiguration(bean.getConfiguration()); // Note: we do not audit the policy configuration since it may have sensitive data } policy.setModifiedOn(new Date()); policy.setModifiedBy(this.securityContext.getCurrentUser()); storage.updatePolicy(policy); storage.createAuditEntry(AuditUtils.policyUpdated(policy, PolicyType.Plan, securityContext)); storage.commitTx(); log.debug(String.format("Updated plan policy %s", policy)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#deletePlanPolicy(java.lang.String, java.lang.String, java.lang.String, long) */ @Override public void deletePlanPolicy(String organizationId, String planId, String version, long policyId) throws OrganizationNotFoundException, PlanVersionNotFoundException, PolicyNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.planEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the plan version exists PlanVersionBean plan = getPlanVersion(organizationId, planId, version); if (plan.getStatus() == PlanStatus.Locked) { throw ExceptionFactory.invalidPlanStatusException(); } try { storage.beginTx(); PolicyBean policy = this.storage.getPolicy(PolicyType.Plan, organizationId, planId, version, policyId); if (policy == null) { throw ExceptionFactory.policyNotFoundException(policyId); } storage.deletePolicy(policy); storage.createAuditEntry(AuditUtils.policyRemoved(policy, PolicyType.Plan, securityContext)); storage.commitTx(); log.debug(String.format("Deleted plan policy %s", policy)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listPlanPolicies(java.lang.String, java.lang.String, java.lang.String) */ @Override public List<PolicySummaryBean> listPlanPolicies(String organizationId, String planId, String version) throws OrganizationNotFoundException, PlanVersionNotFoundException, NotAuthorizedException { // Try to get the plan first - will throw an exception if not found. getPlanVersion(organizationId, planId, version); try { return query.getPolicies(organizationId, planId, version, PolicyType.Plan); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#reorderPlanPolicies(java.lang.String, java.lang.String, java.lang.String, io.apiman.manager.api.beans.policies.PolicyChainBean) */ @Override public void reorderPlanPolicies(String organizationId, String planId, String version, PolicyChainBean policyChain) throws OrganizationNotFoundException, PlanVersionNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.planEdit, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Make sure the plan version exists PlanVersionBean pvb = getPlanVersion(organizationId, planId, version); try { storage.beginTx(); List<Long> newOrder = new ArrayList<>(policyChain.getPolicies().size()); for (PolicySummaryBean psb : policyChain.getPolicies()) { newOrder.add(psb.getId()); } storage.reorderPolicies(PolicyType.Plan, organizationId, planId, version, newOrder); storage.createAuditEntry(AuditUtils.policiesReordered(pvb, PolicyType.Plan, securityContext)); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * Creates a policy for the given entity (supports creating policies for applications, * services, and plans). * * @param organizationId * @param entityId * @param entityVersion * @param bean * @return the stored policy bean (with updated information) * @throws NotAuthorizedException */ protected PolicyBean doCreatePolicy(String organizationId, String entityId, String entityVersion, NewPolicyBean bean, PolicyType type) throws PolicyDefinitionNotFoundException { if (bean.getDefinitionId() == null) { ExceptionFactory.policyDefNotFoundException("null"); //$NON-NLS-1$ } PolicyDefinitionBean def = null; try { storage.beginTx(); def = storage.getPolicyDefinition(bean.getDefinitionId()); if (def == null) { throw ExceptionFactory.policyDefNotFoundException(bean.getDefinitionId()); } storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } int newIdx = 0; try { newIdx = query.getMaxPolicyOrderIndex(organizationId, entityId, entityVersion, type) + 1; } catch (StorageException e) { throw new SystemErrorException(e); } try { PolicyBean policy = new PolicyBean(); policy.setId(null); policy.setDefinition(def); policy.setName(def.getName()); policy.setConfiguration(bean.getConfiguration()); policy.setCreatedBy(securityContext.getCurrentUser()); policy.setCreatedOn(new Date()); policy.setModifiedBy(securityContext.getCurrentUser()); policy.setModifiedOn(new Date()); policy.setOrganizationId(organizationId); policy.setEntityId(entityId); policy.setEntityVersion(entityVersion); policy.setType(type); policy.setOrderIndex(newIdx); storage.beginTx(); storage.createPolicy(policy); storage.createAuditEntry(AuditUtils.policyAdded(policy, type, securityContext)); storage.commitTx(); PolicyTemplateUtil.generatePolicyDescription(policy); log.debug(String.format("Created app policy: %s", policy)); //$NON-NLS-1$ return policy; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#grant(java.lang.String, io.apiman.manager.api.beans.idm.GrantRolesBean) */ @Override public void grant(String organizationId, GrantRolesBean bean) throws OrganizationNotFoundException, RoleNotFoundException, UserNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.orgAdmin, organizationId)) throw ExceptionFactory.notAuthorizedException(); // Verify that the references are valid. get(organizationId); users.get(bean.getUserId()); for (String roleId : bean.getRoleIds()) { roles.get(roleId); } MembershipData auditData = new MembershipData(); auditData.setUserId(bean.getUserId()); try { for (String roleId : bean.getRoleIds()) { RoleMembershipBean membership = RoleMembershipBean.create(bean.getUserId(), roleId, organizationId); membership.setCreatedOn(new Date()); // If the membership already exists, that's fine! if (idmStorage.getMembership(bean.getUserId(), roleId, organizationId) == null) { idmStorage.createMembership(membership); } auditData.addRole(roleId); } } catch (StorageException e) { throw new SystemErrorException(e); } try { storage.beginTx(); storage.createAuditEntry(AuditUtils.membershipGranted(organizationId, auditData, securityContext)); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#revoke(java.lang.String, java.lang.String, java.lang.String) */ @Override public void revoke(String organizationId, String roleId, String userId) throws OrganizationNotFoundException, RoleNotFoundException, UserNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.orgAdmin, organizationId)) throw ExceptionFactory.notAuthorizedException(); get(organizationId); users.get(userId); roles.get(roleId); MembershipData auditData = new MembershipData(); auditData.setUserId(userId); boolean revoked = false; try { idmStorage.deleteMembership(userId, roleId, organizationId); auditData.addRole(roleId); revoked = true; } catch (StorageException e) { throw new SystemErrorException(e); } if (revoked) { try { storage.beginTx(); storage.createAuditEntry(AuditUtils.membershipRevoked(organizationId, auditData, securityContext)); storage.commitTx(); log.debug(String.format("Revoked User %s Role %s Org %s", userId, roleId, organizationId)); //$NON-NLS-1$ } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#revokeAll(java.lang.String, java.lang.String) */ @Override public void revokeAll(String organizationId, String userId) throws OrganizationNotFoundException, RoleNotFoundException, UserNotFoundException, NotAuthorizedException { if (!securityContext.hasPermission(PermissionType.orgAdmin, organizationId)) throw ExceptionFactory.notAuthorizedException(); get(organizationId); users.get(userId); try { idmStorage.deleteMemberships(userId, organizationId); } catch (StorageException e) { throw new SystemErrorException(e); } MembershipData auditData = new MembershipData(); auditData.setUserId(userId); auditData.addRole("*"); //$NON-NLS-1$ try { storage.beginTx(); storage.createAuditEntry(AuditUtils.membershipRevoked(organizationId, auditData, securityContext)); storage.commitTx(); } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @see io.apiman.manager.api.rest.contract.IOrganizationResource#listMembers(java.lang.String) */ @Override public List<MemberBean> listMembers(String organizationId) throws OrganizationNotFoundException, NotAuthorizedException { get(organizationId); try { Set<RoleMembershipBean> memberships = idmStorage.getOrgMemberships(organizationId); TreeMap<String, MemberBean> members = new TreeMap<>(); for (RoleMembershipBean membershipBean : memberships) { String userId = membershipBean.getUserId(); MemberBean member = members.get(userId); if (member == null) { UserBean user = idmStorage.getUser(userId); member = new MemberBean(); member.setEmail(user.getEmail()); member.setUserId(userId); member.setUserName(user.getFullName()); member.setRoles(new ArrayList<MemberRoleBean>()); members.put(userId, member); } String roleId = membershipBean.getRoleId(); RoleBean role = idmStorage.getRole(roleId); MemberRoleBean mrb = new MemberRoleBean(); mrb.setRoleId(roleId); mrb.setRoleName(role.getName()); member.getRoles().add(mrb); if (member.getJoinedOn() == null || membershipBean.getCreatedOn().compareTo(member.getJoinedOn()) < 0) { member.setJoinedOn(membershipBean.getCreatedOn()); } } return new ArrayList<>(members.values()); } catch (StorageException e) { throw new SystemErrorException(e); } } /** * Gets a policy by its id. Also verifies that the policy really does belong to * the entity indicated. * @param type * @param organizationId * @param entityId * @param entityVersion * @param policyId * @return a policy bean * @throws PolicyNotFoundException */ protected PolicyBean doGetPolicy(PolicyType type, String organizationId, String entityId, String entityVersion, long policyId) throws PolicyNotFoundException { try { storage.beginTx(); PolicyBean policy = storage.getPolicy(type, organizationId, entityId, entityVersion, policyId); if (policy == null) { throw ExceptionFactory.policyNotFoundException(policyId); } storage.commitTx(); if (policy.getType() != type) { throw ExceptionFactory.policyNotFoundException(policyId); } if (!policy.getOrganizationId().equals(organizationId)) { throw ExceptionFactory.policyNotFoundException(policyId); } if (!policy.getEntityId().equals(entityId)) { throw ExceptionFactory.policyNotFoundException(policyId); } if (!policy.getEntityVersion().equals(entityVersion)) { throw ExceptionFactory.policyNotFoundException(policyId); } PolicyTemplateUtil.generatePolicyDescription(policy); return policy; } catch (AbstractRestException e) { storage.rollbackTx(); throw e; } catch (Exception e) { storage.rollbackTx(); throw new SystemErrorException(e); } } /** * @return a {@link GatewayBean} iff there is a single configured gateway in the system * @throws StorageException */ private GatewaySummaryBean getSingularGateway() throws StorageException { List<GatewaySummaryBean> gateways = query.listGateways(); if (gateways != null && gateways.size() == 1) { return gateways.get(0); } else { return null; } } /** * @param svb */ private void decryptEndpointProperties(ServiceVersionBean svb) { Map<String, String> endpointProperties = svb.getEndpointProperties(); if (endpointProperties != null) { for (Entry<String, String> entry : endpointProperties.entrySet()) { entry.setValue(AesEncrypter.decrypt(entry.getValue())); } } } /** * @param svb */ private void encryptEndpointProperties(ServiceVersionBean svb) { Map<String, String> endpointProperties = svb.getEndpointProperties(); if (endpointProperties != null) { for (Entry<String, String> entry : endpointProperties.entrySet()) { entry.setValue(AesEncrypter.encrypt(entry.getValue())); } } } /** * @return the storage */ public IStorage getStorage() { return storage; } /** * @param storage the storage to set */ public void setStorage(IStorage storage) { this.storage = storage; } /** * @return the idmStorage */ public IIdmStorage getIdmStorage() { return idmStorage; } /** * @param idmStorage the idmStorage to set */ public void setIdmStorage(IIdmStorage idmStorage) { this.idmStorage = idmStorage; } /** * @return the users */ public IUserResource getUsers() { return users; } /** * @param users the users to set */ public void setUsers(IUserResource users) { this.users = users; } /** * @return the roles */ public IRoleResource getRoles() { return roles; } /** * @param roles the roles to set */ public void setRoles(IRoleResource roles) { this.roles = roles; } /** * @return the securityContext */ public ISecurityContext getSecurityContext() { return securityContext; } /** * @param securityContext the securityContext to set */ public void setSecurityContext(ISecurityContext securityContext) { this.securityContext = securityContext; } /** * @return the query */ public IStorageQuery getQuery() { return query; } /** * @param query the query to set */ public void setQuery(IStorageQuery query) { this.query = query; } /** * @return the metrics */ public IMetricsAccessor getMetrics() { return this.metrics; } /** * @param metrics the metrics to set */ public void setMetrics(IMetricsAccessor metrics) { this.metrics = metrics; } /** * @return the applicationValidator */ public IApplicationValidator getApplicationValidator() { return applicationValidator; } /** * @param applicationValidator the applicationValidator to set */ public void setApplicationValidator(IApplicationValidator applicationValidator) { this.applicationValidator = applicationValidator; } /** * @return the serviceValidator */ public IServiceValidator getServiceValidator() { return serviceValidator; } /** * @param serviceValidator the serviceValidator to set */ public void setServiceValidator(IServiceValidator serviceValidator) { this.serviceValidator = serviceValidator; } /** * @return the apiKeyGenerator */ public IApiKeyGenerator getApiKeyGenerator() { return apiKeyGenerator; } /** * @param apiKeyGenerator the apiKeyGenerator to set */ public void setApiKeyGenerator(IApiKeyGenerator apiKeyGenerator) { this.apiKeyGenerator = apiKeyGenerator; } /** * Parse the to date query param. * @param fromDate */ private DateTime parseFromDate(String fromDate) { // Default to the last 30 days DateTime defaultFrom = DateTime.now().withZone(DateTimeZone.UTC).minusDays(30).withHourOfDay(0) .withMinuteOfHour(0).withSecondOfMinute(0).withMillisOfSecond(0); return parseDate(fromDate, defaultFrom, true); } /** * Parse the from date query param. * @param fromDate */ private DateTime parseToDate(String toDate) { // Default to now return parseDate(toDate, DateTime.now().withZone(DateTimeZone.UTC), false); } /** * Parses a query param representing a date into an actual date object. * @param dateStr * @param defaultDate * @param floor */ private static DateTime parseDate(String dateStr, DateTime defaultDate, boolean floor) { if ("now".equals(dateStr)) { //$NON-NLS-1$ return DateTime.now(); } if (dateStr.length() == 10) { DateTime parsed = ISODateTimeFormat.date().withZoneUTC().parseDateTime(dateStr); // If what we want is the floor, then just return it. But if we want the // ceiling of the date, then we need to set the right params. if (!floor) { parsed = parsed.plusDays(1).minusMillis(1); } return parsed; } if (dateStr.length() == 20) { return ISODateTimeFormat.dateTimeNoMillis().withZoneUTC().parseDateTime(dateStr); } if (dateStr.length() == 24) { return ISODateTimeFormat.dateTime().withZoneUTC().parseDateTime(dateStr); } return defaultDate; } /** * Ensures that the given date range is valid. * @param from * @param to */ private void validateMetricRange(DateTime from, DateTime to) throws InvalidMetricCriteriaException { if (from.isAfter(to)) { throw ExceptionFactory.invalidMetricCriteriaException( Messages.i18n.format("OrganizationResourceImpl.InvalidMetricDateRange")); //$NON-NLS-1$ } } /** * Ensures that a time series can be created for the given date range and * interval, and that the * @param from * @param to * @param interval */ private void validateTimeSeriesMetric(DateTime from, DateTime to, HistogramIntervalType interval) throws InvalidMetricCriteriaException { long millis = to.getMillis() - from.getMillis(); long divBy = ONE_DAY_MILLIS; switch (interval) { case day: divBy = ONE_DAY_MILLIS; break; case hour: divBy = ONE_HOUR_MILLIS; break; case minute: divBy = ONE_MINUTE_MILLIS; break; case month: divBy = ONE_MONTH_MILLIS; break; case week: divBy = ONE_WEEK_MILLIS; break; default: break; } long totalDataPoints = millis / divBy; if (totalDataPoints > 5000) { throw ExceptionFactory.invalidMetricCriteriaException( Messages.i18n.format("OrganizationResourceImpl.MetricDataSetTooLarge")); //$NON-NLS-1$ } } }