docs: private void retireApi(ActionBean action) throws ActionException {
          if (!securityContext.hasPermission(PermissionType.apiAdmin, action.getOrganizationId()))
              throw ExceptionFactory.notAuthorizedException();
  
          ApiVersionBean versionBean;
          try {
              versionBean = orgs.getApiVersion(action.getOrganizationId(), action.getEntityId(), action.getEntityVersion());
          } catch (ApiVersionNotFoundException e) {
              throw ExceptionFactory.actionException(Messages.i18n.format("ApiNotFound")); //$NON-NLS-1$
          }
  
          // Validate that it's ok to perform this action - API must be Published.
          if (versionBean.getStatus() != ApiStatus.Published) {
              throw ExceptionFactory.actionException(Messages.i18n.format("InvalidApiStatus")); //$NON-NLS-1$
          }
  
          Api gatewayApi = new Api();
          gatewayApi.setOrganizationId(versionBean.getApi().getOrganization().getId());
          gatewayApi.setApiId(versionBean.getApi().getId());
          gatewayApi.setVersion(versionBean.getVersion());
  
          // Retire the API from all relevant gateways
          try {
              storage.beginTx();
              Set<ApiGatewayBean> gateways = versionBean.getGateways();
              if (gateways == null) {
                  throw new PublishingException("No gateways specified for API!"); //$NON-NLS-1$
              }
              for (ApiGatewayBean apiGatewayBean : gateways) {
                  IGatewayLink gatewayLink = createGatewayLink(apiGatewayBean.getGatewayId());
                  gatewayLink.retireApi(gatewayApi);
                  gatewayLink.close();
              }
  
              versionBean.setStatus(ApiStatus.Retired);
              versionBean.setRetiredOn(new Date());
  
              ApiBean api = storage.getApi(action.getOrganizationId(), action.getEntityId());
              if (api == null) {
                  throw new PublishingException("Error: could not find API - " + action.getOrganizationId() + "=>" + action.getEntityId()); //$NON-NLS-1$ //$NON-NLS-2$
              }
              if (api.getNumPublished() == null || api.getNumPublished() == 0) {
                  api.setNumPublished(0);
              } else {
                  api.setNumPublished(api.getNumPublished() - 1);
              }
  
              storage.updateApi(api);
              storage.updateApiVersion(versionBean);
              storage.createAuditEntry(AuditUtils.apiRetired(versionBean, securityContext));
              storage.commitTx();
          } catch (PublishingException e) {
              storage.rollbackTx();
              throw ExceptionFactory.actionException(Messages.i18n.format("RetireError"), e); //$NON-NLS-1$
          } catch (Exception e) {
              storage.rollbackTx();
              throw ExceptionFactory.actionException(Messages.i18n.format("RetireError"), e); //$NON-NLS-1$
          }
  
          log.debug(String.format("Successfully retired API %s on specified gateways: %s", //$NON-NLS-1$
                  versionBean.getApi().getName(), versionBean.getApi()));
      }