class ClouderaManagerClusterCreationSetupService {

    public List<ClusterComponent> prepareClouderaManagerCluster(ClusterV4Request request, Cluster cluster,
            Optional<Component> stackClouderaManagerRepoConfig,
            List<Component> stackCdhRepoConfig,
            Optional<Component> stackImageComponent) throws IOException, CloudbreakImageCatalogException {
        List<ClusterComponent> components = new ArrayList<>();
        long start = System.currentTimeMillis();
        String blueprintCdhVersion = blueprintUtils.getCDHStackVersion(JsonUtil.readTree(cluster.getBlueprint().getBlueprintText()));
        LOGGER.debug("blueprintUtils.getCDHStackVersion took {} ms", System.currentTimeMillis() - start);

        Optional<ClouderaManagerRepositoryV4Request> cmRepoRequest = measure(() ->
                Optional.ofNullable(request.getCm()).map(ClouderaManagerV4Request::getRepository),
                LOGGER,
                "ClouderaManagerV4Request::getRepository {} ms");

        start = System.currentTimeMillis();
        String osType = getOsType(stackImageComponent);
        String imageCatalogName = getImageCatalogName(stackImageComponent);
        LOGGER.debug("getImageCatalogName took {} ms", System.currentTimeMillis() - start);

        start = System.currentTimeMillis();
        ClusterComponent cmRepoConfig = getCmRepoConfiguration(cluster, stackClouderaManagerRepoConfig, components, blueprintCdhVersion, cmRepoRequest, osType);
        LOGGER.debug("getCmRepoConfiguration took {} ms", System.currentTimeMillis() - start);

        start = System.currentTimeMillis();
        checkCmStackRepositories(cmRepoConfig, stackImageComponent.get());
        LOGGER.debug("checkCmStackRepositories took {} ms", System.currentTimeMillis() - start);

        start = System.currentTimeMillis();
        addProductComponentsToCluster(request, cluster, stackCdhRepoConfig, components, blueprintCdhVersion, osType, imageCatalogName);
        LOGGER.debug("addProductComponentsToCluster took {} ms", System.currentTimeMillis() - start);

        return components;
    }

}