class ClouderaManagerModificationService implements ClusterModificationService {

    @Override
    public void upgradeClusterRuntime(Set<ClusterComponent> components, boolean patchUpgrade) throws CloudbreakException {
        try {
            ClusterComponent stackComponent = getStackComponent(components);

            ClouderaManagerProduct stackProduct = stackComponent.getAttributes().get(ClouderaManagerProduct.class);
            String stackProductVersion = stackProduct.getVersion();
            String stackProductParcel = stackProduct.getParcel();
            String product = com.sequenceiq.cloudbreak.cloud.model.component.StackType.CDH.name();

            ClustersResourceApi clustersResourceApi = clouderaManagerApiFactory.getClustersResourceApi(apiClient);
            ParcelsResourceApi parcelsResourceApi = clouderaManagerApiFactory.getParcelsResourceApi(apiClient);
            ParcelResourceApi parcelResourceApi = clouderaManagerApiFactory.getParcelResourceApi(apiClient);
            MgmtServiceResourceApi mgmtServiceResourceApi = clouderaManagerApiFactory.getMgmtServiceResourceApi(apiClient);
            ClouderaManagerResourceApi clouderaManagerResourceApi = clouderaManagerApiFactory.getClouderaManagerResourceApi(apiClient);

            startClouderaManager(stack, apiClient);
            checkParcelApiAvailability();
            setParcelRepo(stackProductParcel, clouderaManagerResourceApi);
            refreshParcelRepos(clouderaManagerResourceApi);
            downloadParcel(stackProductVersion, parcelResourceApi, product);
            distributeParcel(stackProductVersion, parcelResourceApi, product);
            if (patchUpgrade) {
                activateParcel(stackProductVersion, parcelResourceApi, product);
                restartServices(clustersResourceApi);
            } else {
                callUpgradeCdhCommand(stackProductVersion, clustersResourceApi);
                restartStaleServices(mgmtServiceResourceApi, clustersResourceApi);
            }
            clouderaManagerParcelService.removeUnusedParcelVersions(apiClient, parcelsResourceApi, parcelResourceApi, stack, product, stackProductVersion);
            configService.enableKnoxAutorestartIfCmVersionAtLeast(CLOUDERAMANAGER_VERSION_7_1_0, apiClient, stack.getName());
        } catch (ApiException | IOException e) {
            LOGGER.info("Could not upgrade Cloudera Runtime services", e);
            throw new ClouderaManagerOperationFailedException(e.getMessage(), e);
        }
    }

    public  ClouderaManagerModificationService(Stack stack, HttpClientConfig clientConfig);

}