All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cds.feature.mt.SaasClient Maven / Gradle / Ivy

There is a newer version: 3.6.0
Show newest version
package com.sap.cds.feature.mt;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.google.common.base.Objects;
import com.sap.cds.integration.cloudsdk.rest.client.JsonRestClient;
import com.sap.cds.services.environment.ServiceBinding;
import com.sap.cds.services.runtime.CdsRuntime;
import com.sap.cloud.sdk.cloudplatform.connectivity.OnBehalfOf;


/**
 * Implementation of the SaaS Registry REST client.
 */
public class SaasClient extends JsonRestClient {

	private static final Logger logger = LoggerFactory.getLogger(SaasClient.class);

	// could be configurable via CdsProperties
	private static final int PAGE_SIZE = 500;

	private static final String TENANT_STATE = "state";
	private static final String SAAS_REGISTRY = "saas-registry";

	private static final String SAAS_MANAGER_BASE = "/saas-manager/v1/";
	private static final String APPLICATION_TENANTS_PATH = SAAS_MANAGER_BASE + "application/subscriptions";
	private static final String SERVICE_TENANTS_PATH = SAAS_MANAGER_BASE + "service/subscriptions?includeIndirectSubscriptions=true";

	private final String urlPath;

	public static Optional findBinding(CdsRuntime runtime) {
		return runtime.getEnvironment().getServiceBindings().filter(b -> b.matches(null, SAAS_REGISTRY)).findFirst();
	}

	public SaasClient(ServiceBinding binding) {
		super(getSaasUrl(binding), checkBinding(binding), OnBehalfOf.TECHNICAL_USER_PROVIDER);
		this.urlPath = "service".equals(binding.getServicePlan()) ? SERVICE_TENANTS_PATH : APPLICATION_TENANTS_PATH;
	}

	/**
	 * Retrieves the tenant info of all subscribed tenants
	 *
	 * @return tenants info
	 *
	 * @throws IOException throws when any connection problems occur
	 */
	public List> getSubscribedTenants() throws IOException {

		logger.debug("Retrieving all tenants metadata from the SaaS registry");

		List> result = new ArrayList<>();
		boolean morePages = true;
		int page = 1;

		while (morePages) {
			logger.debug("Retrieving page {} of all tenants metadata from the SaaS registry", page);

			String paginatedUrlPath = paginatedUrl(urlPath, page);
			JsonNode jsonResponse = getRequest(paginatedUrlPath);
			ArrayNode resp = getNode(jsonResponse, "subscriptions");
			BooleanNode morePagesResp = getNode(jsonResponse, "morePages");

			resp.forEach(tenant -> {
				String state = tenant.get(TENANT_STATE) != null ? tenant.get(TENANT_STATE).asText() : null;
				if (Objects.equal(state, "SUBSCRIBED") || Objects.equal(state, "UPDATE_FAILED")) {
					result.add(mapper.convertValue(tenant, new TypeReference>() {
					}));
				}
			});

			morePages = morePagesResp != null && morePagesResp.booleanValue();
			page = page + 1;

			logger.debug("More tenants metadata from the SaaS registry available: {}", morePages ? "yes" : "no");
		}

		return result;
	}

	private String paginatedUrl(String urlPath, int page) {
		String url = urlPath + (urlPath.contains("?") ? "&" : "?");

		url = url + "page=" + page + "&size=" + PAGE_SIZE;

		return url;
	}

	@SuppressWarnings("unchecked")
	private   N getNode(JsonNode jsonResponse, String keyName) {
		return (N) jsonResponse.get(keyName);
	}

	private static String getSaasUrl(ServiceBinding binding) {
		return binding.getCredentials().get("saas_registry_url").toString();
	}

	private static ServiceBinding checkBinding(ServiceBinding binding) {
		// TODO: workaround as the saas binding has old binding structure
		if (binding.getCredentials().get("uaa") == null) {
			return new ServiceBinding() {

				@Override
				public List getTags() {
					return binding.getTags();
				}

				@Override
				public String getServicePlan() {
					return binding.getServicePlan();
				}

				@Override
				public String getService() {
					return binding.getService();
				}

				@Override
				public String getName() {
					return binding.getName();
				}

				@Override
				public Map getCredentials() {
					Map credentials = new HashMap<>();
					binding.getCredentials().forEach(credentials::put);
					credentials.put("uaa", binding.getCredentials());
					return credentials;
				}
			};
		}
		return binding;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy