package org.gcube.portlets.admin.systemservicedefinition.is; import java.util.ArrayList; import java.util.List; import org.gcube.common.encryption.encrypter.StringEncrypter; import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.informationsystem.publisher.RegistryPublisher; import org.gcube.informationsystem.publisher.RegistryPublisherFactory; import org.gcube.portlets.admin.systemservicedefinition.definition.DefinitionItem; import org.gcube.portlets.admin.systemservicedefinition.shared.Constants; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.SimpleQuery; import org.gcube.resources.discovery.icclient.ICFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Giancarlo Panichi * */ public class InformationSystemUtils { private static Logger logger = LoggerFactory.getLogger(InformationSystemUtils.class); public static IAMService retrieveIAMService(String scope) throws Exception { try { logger.debug("Retrieve IAM Service on IS"); if (scope == null || scope.isEmpty()) throw new Exception("Invalid scope: " + scope); /* * if (token == null || token.isEmpty()) throw new Exception("Invalid token: " + * scope); */ ScopeProvider.instance.set(scope); // AccessTokenProvider.instance.set(token); // SecurityTokenProvider.instance.set(token); SimpleQuery query = ICFactory.queryFor(ServiceEndpoint.class); query.addCondition("$resource/Profile/Category/text() eq '" + Constants.IAM_SERVICE_CATEGORY + "'") .addCondition("$resource/Profile/Name/text() eq '" + Constants.IAM_SERVICE_NAME + "'"); DiscoveryClient client = ICFactory.clientFor(ServiceEndpoint.class); List resources = client.submit(query); IAMService iamService = null; if (resources != null && !resources.isEmpty()) { ServiceEndpoint iams = resources.get(0); iamService = new IAMService(iams.profile().runtime().hostedOn()); } logger.debug("IAM Services retrieved: {}", iamService); return iamService; } catch (Throwable e) { logger.error("Error in discovery IAM Service Endpoint in scope: " + scope); logger.error(e.getLocalizedMessage(), e); throw e; } } public static void checkSSDPresent(DefinitionItem definitionItem, String category, String scope) throws Exception { try { if (definitionItem == null || definitionItem.getClientId() == null || definitionItem.getClientId().isEmpty()) throw new Exception("Invalid definition: " + definitionItem); if (category == null || category.isEmpty()) throw new Exception("Invalid category: " + category); if (scope == null || scope.isEmpty()) throw new Exception("Invalid scope: " + scope); ScopeProvider.instance.set(scope); // AccessTokenProvider.instance.set(token); // SecurityTokenProvider.instance.set(token); SimpleQuery query = ICFactory.queryFor(ServiceEndpoint.class); query.addCondition("$resource/Profile/Category/text() eq '" + category + "'") .addCondition("$resource/Profile/Name/text() eq '" + definitionItem.getClientId() + "'"); DiscoveryClient client = ICFactory.clientFor(ServiceEndpoint.class); List resources = client.submit(query); for(ServiceEndpoint ssd: resources) { if (definitionItem.getClientId().compareTo(ssd.profile().name()) == 0) { StringBuilder error=new StringBuilder(); error.append("System Service "); error.append(definitionItem.getClientId()); error.append(" already present in the scope: "); error.append(scope); logger.error(error.toString()); throw new Exception(error.toString()); } } logger.debug("System Service not already present on IS in scope: "+scope); return ; } catch (Throwable e) { logger.error(e.getLocalizedMessage(), e); throw e; } } public static ArrayList retrieveSSD(String category, String scope) throws Exception { try { logger.debug("Retrieve System Services Definition on IS"); if (category == null || category.isEmpty()) throw new Exception("Invalid category: " + category); if (scope == null || scope.isEmpty()) throw new Exception("Invalid scope: " + scope); /* * if (token == null || token.isEmpty()) throw new Exception("Invalid token: " + * scope); */ ScopeProvider.instance.set(scope); // AccessTokenProvider.instance.set(token); // SecurityTokenProvider.instance.set(token); SimpleQuery query = ICFactory.queryFor(ServiceEndpoint.class); query.addCondition("$resource/Profile/Category/text() eq '" + category + "'"); DiscoveryClient client = ICFactory.clientFor(ServiceEndpoint.class); List resources = client.submit(query); logger.debug("Retrieved: " + resources); ArrayList ssdList = new ArrayList(); for (ServiceEndpoint se : resources) { String username = null; String password = null; for (AccessPoint accessPoint : se.profile().accessPoints()) { username = accessPoint.username(); String decryptedSecret = StringEncrypter.getEncrypter().decrypt(accessPoint.password()); password = decryptedSecret; break; } DefinitionItem definitionItem = new DefinitionItem(se.profile().name(), se.profile().description(), username, password); ssdList.add(definitionItem); } logger.debug("SSDList: {}", ssdList); return ssdList; } catch (Throwable e) { logger.error("Error in discovery System Services Endpoint in scope: " + scope); logger.error(e.getLocalizedMessage(), e); throw e; } } public static void publishSSD(DefinitionItem definitionItem, String category, String scope) throws Exception { if (definitionItem == null) throw new Exception("Invalid definition: " + definitionItem); if (category == null || category.isEmpty()) throw new Exception("Invalid category: " + category); if (scope == null || scope.isEmpty()) throw new Exception("Invalid scope: " + scope); /* * if (token == null || token.isEmpty()) throw new Exception("Invalid token: " + * token); */ checkSSDPresent(definitionItem, category, scope); IAMService iamService = retrieveIAMService(scope); ServiceEndpoint toPublish = new ServiceEndpoint(); logger.debug("Resource Type: {}", toPublish.type()); /* * List scopes = new ArrayList(); scopes.add(scope); * Collection col = toPublish.scopes().asCollection(); * col.addAll(scopes); */ toPublish.newProfile(); toPublish.profile().name(definitionItem.getClientId()); toPublish.profile().description(definitionItem.getDescription()); toPublish.profile().category(category); toPublish.profile().version("1.0.0"); toPublish.profile().newRuntime(); toPublish.profile().runtime().ghnId(""); toPublish.profile().runtime().status("READY"); toPublish.profile().runtime().hostedOn("d4science.org"); toPublish.profile().newPlatform(); toPublish.profile().platform().name("d4science"); toPublish.profile().platform().version((short) 0); toPublish.profile().platform().minorVersion((short) 0); toPublish.profile().platform().revisionVersion((short) 0); toPublish.profile().platform().buildVersion((short) 0); AccessPoint accessPoint = new AccessPoint(); String encryptedPassword = StringEncrypter.getEncrypter().encrypt(definitionItem.getSecret()); accessPoint.name(definitionItem.getClientId()); accessPoint.description("Keycloak client credentials"); accessPoint.address(iamService.getAddress()); accessPoint.credentials(encryptedPassword, definitionItem.getUsername()); toPublish.profile().accessPoints().add(accessPoint); logger.debug("Request publish: {}", toPublish); try { // AccessTokenProvider.instance.set(token); // SecurityTokenProvider.instance.set(token); ScopeProvider.instance.set(scope); RegistryPublisher publisher = RegistryPublisherFactory.create(); String id = publisher.create(toPublish).id(); logger.debug("Created new RR sent, Got from publisher: id=" + id); // ScopedPublisher sp=RegistryPublisherFactory.scopedPublisher(); // toPublish = sp.create(toPublish,scopes); } catch (Exception e) { logger.error("Error publishing the ssd on IS: {}", e.getLocalizedMessage(), e); throw e; } logger.debug("Published on IS"); } public static void deleteSSD(DefinitionItem definitionItem, String category, String scope) throws Exception { if (definitionItem == null) throw new Exception("Invalid definition: " + definitionItem); if (category == null || category.isEmpty()) throw new Exception("Invalid category: " + category); if (scope == null || scope.isEmpty()) throw new Exception("Invalid scope: " + scope); ScopeProvider.instance.set(scope); // AccessTokenProvider.instance.set(token); // SecurityTokenProvider.instance.set(token); SimpleQuery query = ICFactory.queryFor(ServiceEndpoint.class); query.addCondition("$resource/Profile/Category/text() eq '" + category + "'") .addCondition("$resource/Profile/Name/text() eq '" + definitionItem.getClientId() + "'"); DiscoveryClient client = ICFactory.clientFor(ServiceEndpoint.class); List resources = client.submit(query); if (resources != null && !resources.isEmpty()) { ServiceEndpoint toDelete = resources.get(0); logger.debug("Requested delete: {}", toDelete); try { RegistryPublisher publisher = RegistryPublisherFactory.create(); publisher.remove(toDelete); } catch (Exception e) { logger.error("Error publishing the ssd on IS: {}", e.getLocalizedMessage(), e); throw e; } logger.debug("Deleted on IS"); } else { String error = "No resources found with name: " + definitionItem.getClientId(); logger.error(error); throw new Exception(error); } } }