public void registerClient(String orgId, String clientId, String clientVersion) throws ActionException, NotAuthorizedException {
        ClientVersionBean versionBean;
        List<ContractSummaryBean> contractBeans;
        try {
            versionBean = clientAppService.getClientVersion(orgId, clientId, clientVersion);
        } catch (ClientVersionNotFoundException e) {
            throw ExceptionFactory.actionException(Messages.i18n.format("clientVersionDoesNotExist", clientId, clientVersion)); //$NON-NLS-1$
        }
        try {
            contractBeans = query.getClientContracts(orgId, clientId, clientVersion);
            // Any awaiting approval then don't let them republish.
            List<ContractSummaryBean> awaitingApproval = contractBeans.stream()
                         .filter(f -> f.getStatus() == ContractStatus.AwaitingApproval)
                         .collect(Collectors.toList());
            if (!awaitingApproval.isEmpty()) {
                throw ExceptionFactory.contractNotYetApprovedException(awaitingApproval);
            }
        } catch (StorageException e) {
            throw ExceptionFactory.actionException(Messages.i18n.format("ClientNotFound"), e); //$NON-NLS-1$
        }

        boolean isReregister = false;

        // Validate that it's ok to perform this action
        if (versionBean.getStatus() == ClientStatus.Registered) {
            Date modOn = versionBean.getModifiedOn();
            Date publishedOn = versionBean.getPublishedOn();
            int c = modOn.compareTo(publishedOn);
            if (c <= 0) {
                throw ExceptionFactory.actionException(Messages.i18n.format("ClientReRegisterNotRequired")); //$NON-NLS-1$
            }
            isReregister = true;
        }

        Client client = new Client();
        client.setOrganizationId(versionBean.getClient().getOrganization().getId());
        client.setClientId(versionBean.getClient().getId());
        client.setVersion(versionBean.getVersion());
        client.setApiKey(versionBean.getApikey());

        Set<Contract> contracts = new HashSet<>();
        for (ContractSummaryBean contractBean : contractBeans) {
            Contract contract = new Contract();
            contract.setPlan(contractBean.getPlanId());
            contract.setApiId(contractBean.getApiId());
            contract.setApiOrgId(contractBean.getApiOrganizationId());
            contract.setApiVersion(contractBean.getApiVersion());
            contract.getPolicies().addAll(contractService.aggregateContractPolicies(contractBean));
            contracts.add(contract);
        }
        client.setContracts(contracts);

        // Next, register the client with *all* relevant gateways.  This is done by
        // looking up all referenced APIs and getting the gateway information for them.
        // Each of those gateways must be told about the client.
        try {
            Map<String, IGatewayLink> links = new HashMap<>();
            for (Contract contract : client.getContracts()) {
                ApiVersionBean svb = storage.getApiVersion(contract.getApiOrgId(), contract.getApiId(), contract.getApiVersion());
                Set<ApiGatewayBean> gateways = svb.getGateways();
                if (gateways == null) {
                    throw new PublishingException("No gateways specified for API: " + svb.getApi().getName()); //$NON-NLS-1$
                }
                for (ApiGatewayBean apiGatewayBean : gateways) {
                    if (!links.containsKey(apiGatewayBean.getGatewayId())) {
                        IGatewayLink gatewayLink = createGatewayLink(apiGatewayBean.getGatewayId());
                        links.put(apiGatewayBean.getGatewayId(), gatewayLink);
                    }
                }
            }
            if (isReregister) {
                // Once we figure out which gateways to register with, make sure we also "unregister"
                // the client app from all other gateways.  This is necessary because we may have broken
                // contracts we previously had on APIs that are published to other gateways.  And thus
                // it's possible we need to remove a contract from a Gateway that is not otherwise/currently
                // referenced.
                //
                // This is a fix for:  https://issues.jboss.org/browse/APIMAN-895

                Iterator<GatewayBean> gateways = storage.getAllGateways();
                while (gateways.hasNext()) {
                    GatewayBean gbean = gateways.next();
                    if (!links.containsKey(gbean.getId())) {
                        IGatewayLink gatewayLink = createGatewayLink(gbean.getId());

                        try {
                            gatewayLink.unregisterClient(client);
                        } catch (Exception e) {
                            // We need to catch the error, but ignore it,
                            // in the event that the gateway is invalid.
                        }

                        gatewayLink.close();
                    }
                }
            }
            for (IGatewayLink gatewayLink : links.values()) {
                gatewayLink.registerClient(client);
                gatewayLink.close();
            }
        } catch (Exception e) {
            throw ExceptionFactory.actionException(Messages.i18n.format("RegisterError"), e); //$NON-NLS-1$
        }

        ClientStatus oldStatus = versionBean.getStatus();
        versionBean.setStatus(ClientStatus.Registered);
        versionBean.setPublishedOn(new Date());

        try {
            storage.updateClientVersion(versionBean);
            storage.createAuditEntry(AuditUtils.clientRegistered(versionBean, securityContext));
            clientAppService.fireClientStatusChangeEvent(versionBean, oldStatus);
        } catch (Exception e) {
            throw ExceptionFactory.actionException(Messages.i18n.format("RegisterError"), e); //$NON-NLS-1$
        }

        LOGGER.debug(String.format("Successfully registered Client %s on specified gateways: %s", //$NON-NLS-1$
             versionBean.getClient().getName(), versionBean.getClient()));
    }
Registers a client (along with all of its contracts) to the gateway.
manager/api/rest-impl/src/main/java/io/apiman/manager/api/service/ActionService.java