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

com.gooddata.project.ProjectService Maven / Gradle / Ivy

There is a newer version: 3.12.0+api3
Show newest version
/*
 * Copyright (C) 2007-2014, GoodData(R) Corporation. All rights reserved.
 */
package com.gooddata.project;

import com.gooddata.AbstractPollHandler;
import com.gooddata.AbstractService;
import com.gooddata.FutureResult;
import com.gooddata.GoodDataException;
import com.gooddata.GoodDataRestException;
import com.gooddata.PollResult;
import com.gooddata.SimplePollHandler;
import com.gooddata.account.AccountService;
import com.gooddata.collections.Page;
import com.gooddata.collections.PageableList;
import com.gooddata.featureflag.FeatureFlagService;
import com.gooddata.gdc.AsyncTask;
import com.gooddata.gdc.FeatureFlag;
import com.gooddata.gdc.FeatureFlags;
import com.gooddata.gdc.UriResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static com.gooddata.gdc.FeatureFlags.AGGREGATED_FEATURE_FLAGS_TEMPLATE;
import static com.gooddata.project.ProjectFeatureFlag.FEATURE_FLAG_TEMPLATE;
import static com.gooddata.project.ProjectFeatureFlags.FEATURE_FLAGS_TEMPLATE;
import static com.gooddata.util.Validate.notEmpty;
import static com.gooddata.util.Validate.notNull;
import static java.util.Arrays.asList;
import static org.springframework.web.util.UriComponentsBuilder.fromUri;

/**
 * List projects, create a project, ...
 * 

* Usage example: *


 *     ProjectService projectService = gd.getProjectService();
 *     Collection<Project> projects = projectService.getProjects();
 *     Project project = projectService.createProject(new Project("my project", "MyToken"));
 * 
*/ public class ProjectService extends AbstractService { private final AccountService accountService; /** * Constructs service for GoodData project management (list projects, create a project, ...). * * @param restTemplate RESTful HTTP Spring template * @param accountService GoodData account service */ public ProjectService(RestTemplate restTemplate, AccountService accountService) { super(restTemplate); this.accountService = notNull(accountService, "accountService"); } /** * Get all projects current user has access to. * * @return collection of all projects current user has access to * @throws com.gooddata.GoodDataException when projects can't be accessed */ public Collection getProjects() { try { final String id = accountService.getCurrent().getId(); final Projects projects = restTemplate.getForObject(Project.PROJECTS_URI, Projects.class, id); return projects.getProjects(); } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to get projects", e); } } /** * Create new project. * * @param project project to be created * @return created project (including very useful id) * @throws com.gooddata.GoodDataException when projects creation fails */ public FutureResult createProject(Project project) { notNull(project, "project"); final UriResponse uri; try { uri = restTemplate.postForObject(Projects.URI, project, UriResponse.class); } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to create project", e); } if (uri == null) { throw new GoodDataException("Empty response when project POSTed to API"); } return new PollResult<>(this, new SimplePollHandler(uri.getUri(), Project.class) { @Override public boolean isFinished(ClientHttpResponse response) throws IOException { final Project project = extractData(response, Project.class); return !project.isPreparing(); } @Override protected void onFinish() { if (!getResult().isEnabled()) { throw new GoodDataException("Created project " + uri + " is not enabled"); } } @Override public void handlePollException(final GoodDataRestException e) { throw new GoodDataException("Creating project " + uri + " failed", e); } }); } /** * Get project by URI. * * @param uri URI of project resource (/gdc/projects/{id}) * @return project * @throws com.gooddata.GoodDataException when project can't be accessed */ public Project getProjectByUri(final String uri) { notEmpty(uri, "uri"); try { return restTemplate.getForObject(uri, Project.class); } catch (GoodDataRestException e) { if (HttpStatus.NOT_FOUND.value() == e.getStatusCode()) { throw new ProjectNotFoundException(uri, e); } else { throw e; } } catch (RestClientException e) { throw new GoodDataException("Unable to get project " + uri, e); } } /** * Get project by id. * * @param id id of project * @return project * @throws com.gooddata.GoodDataException when project can't be accessed */ public Project getProjectById(String id) { notEmpty(id, "id"); return getProjectByUri(Project.TEMPLATE.expand(id).toString()); } /** * Removes given project * @param project project to be removed * @throws com.gooddata.GoodDataException when project can't be deleted */ public void removeProject(final Project project) { notNull(project, "project"); try { restTemplate.delete(project.getUri()); } catch (GoodDataRestException | RestClientException e) { throw new GoodDataException("Unable to delete project " + project.getId(), e); } } public Collection getProjectTemplates(Project project) { notNull(project, "project"); try { final ProjectTemplates templates = restTemplate.getForObject(ProjectTemplate.URI, ProjectTemplates.class, project.getId()); return templates != null && templates.getTemplatesInfo() != null ? templates.getTemplatesInfo() : Collections.emptyList(); } catch (GoodDataRestException | RestClientException e) { throw new GoodDataException("Unable to get project templates", e); } } /** * Get available validation types for project. Which can be passed to {@link #validateProject(Project, ProjectValidationType...)}. * * @param project project to fetch validation types for * @return available validations */ public Set getAvailableProjectValidationTypes(Project project) { notNull(project, "project"); try { return restTemplate.getForObject(ProjectValidations.URI, ProjectValidations.class, project.getId()).getValidations(); } catch (GoodDataRestException | RestClientException e) { throw new GoodDataException("Unable to get project available validation types", e); } } /** * Validate project using all available validations. * * @param project project to validate * @return results of validation */ public FutureResult validateProject(final Project project) { return validateProject(project, getAvailableProjectValidationTypes(project)); } /** * Validate project with given validations * * @param project project to validate * @param validations validations to use * @return results of validation */ public FutureResult validateProject(final Project project, ProjectValidationType... validations) { return validateProject(project, new HashSet<>(asList(validations))); } /** * Validate project with given validations * * @param project project to validate * @param validations validations to use * @return results of validation */ public FutureResult validateProject(final Project project, Set validations) { notNull(project, "project"); final AsyncTask task; try { task = restTemplate.postForObject(ProjectValidations.URI, new ProjectValidations(validations), AsyncTask.class, project.getId()); } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to to start project validation", e); } return new PollResult<>(this, // PollHandler able to poll on different URIs (by the Location header) // poll class is Void because the object returned varies between invocations (even on the same URI) new AbstractPollHandler(task.getUri(), Void.class, ProjectValidationResults.class) { @Override public boolean isFinished(ClientHttpResponse response) throws IOException { final URI location = response.getHeaders().getLocation(); if (location != null) { setPollingUri(location.toString()); } final boolean finished = super.isFinished(response); if (finished) { try { final ProjectValidationResults result = restTemplate.getForObject(getPollingUri(), getResultClass()); setResult(result); } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to obtain validation results from " + getPollingUri()); } } return finished; } @Override public void handlePollResult(final Void pollResult) { } @Override public void handlePollException(final GoodDataRestException e) { throw new GoodDataException("Project validation failed: " + getPollingUri(), e); } }); } /** * Get first page of paged list of users by given project. * * @param project project of users * @return list of found users or empty list */ public List listUsers(Project project) { notNull(project, "project"); return listUsers(getUsersUri(project)); } /** * Get defined page of paged list of users by given project. * * @param project project of users * @param page page to be retrieved * @return list of found users or empty list */ public List listUsers(Project project, Page page) { notNull(project, "project"); notNull(page, "page"); return listUsers(page.getPageUri(fromUri(getUsersUri(project)))); } private PageableList listUsers(URI uri) { try { final Users users = restTemplate.getForObject(uri, Users.class); if (users == null) { return new PageableList<>(); } return users; } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to list users", e); } } private static URI getUsersUri(Project project) { return Users.TEMPLATE.expand(project.getId()); } /** * Get set of user role by given project. * * Note: This makes n+1 API calls to retrieve all role details. * * @param project project of roles * @return set of found roles or empty set */ public Set getRoles(final Project project) { notNull(project, "project"); final Roles roles = restTemplate.getForObject(Roles.URI, Roles.class, project.getId()); final Set result = new HashSet<>(); for (String roleUri : roles.getRoles()) { final Role role = restTemplate.getForObject(roleUri, Role.class); role.setUri(roleUri); result.add(role); } return result; } /** * Get role by given URI. * * @param uri role uri * @return found role * @throws RoleNotFoundException when the role doesn't exist */ public Role getRoleByUri(String uri) { notEmpty(uri, "uri"); try { return restTemplate.getForObject(uri, Role.class); } catch (GoodDataRestException e) { if (HttpStatus.NOT_FOUND.value() == e.getStatusCode()) { throw new RoleNotFoundException(uri, e); } else { throw e; } } catch (RestClientException e) { throw new GoodDataException("Unable to get role " + uri, e); } } /** * Lists aggregated feature flags for given project and current user (aggregates global, project group, project and user feature flags). * It doesn't matter whether feature flag is enabled or not, it'll be included in all cases. * * @param project project, cannot be null * @return list of aggregated feature flags for given project and current user * @deprecated use {@link FeatureFlagService#listFeatureFlags(Project)} instead */ @Deprecated @SuppressWarnings("deprecation") public List listAggregatedFeatureFlags(final Project project) { notNull(project, "project"); try { final FeatureFlags featureFlags = restTemplate.getForObject(AGGREGATED_FEATURE_FLAGS_TEMPLATE.expand(project.getId()), FeatureFlags.class); if (featureFlags == null) { throw new GoodDataException("empty response from API call"); } return featureFlags.getFeatureFlags(); } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to list aggregated feature flags for project ID=" + project.getId(), e); } } /** * Lists all project feature flags (only project scoped flags, use {@link FeatureFlagService#listFeatureFlags(Project)} * for aggregated flags from all scopes). * It doesn't matter whether feature flag is enabled or not, it'll be included in all cases. * * @param project project, cannot be null * @return list of all feature flags for given project * @deprecated use {@link FeatureFlagService#listProjectFeatureFlags(Project)} instead */ @Deprecated @SuppressWarnings("deprecation") public List listFeatureFlags(Project project) { notNull(project, "project"); try { final ProjectFeatureFlags projectFeatureFlags = restTemplate.getForObject(FEATURE_FLAGS_TEMPLATE.expand(project.getId()), ProjectFeatureFlags.class); if (projectFeatureFlags == null) { throw new GoodDataException("empty response from API call"); } return projectFeatureFlags.getItems(); } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to list project feature flags for project ID=" + project.getId(), e); } } /** * Creates new feature flag for given project. * * Usually, it doesn't make sense to create feature flag that is disabled because * this is the same as having no feature flag at all. * * @param project project for which the feature flag should be created, cannot be null * @param featureFlag feature flag to be created, cannot be null * @return created feature flag * @deprecated use {@link FeatureFlagService#createProjectFeatureFlag(Project, com.gooddata.featureflag.ProjectFeatureFlag)} */ @Deprecated @SuppressWarnings("deprecation") public ProjectFeatureFlag createFeatureFlag(final Project project, final ProjectFeatureFlag featureFlag) { notNull(project, "project"); notNull(featureFlag, "featureFlag"); final String featureFlagsUri = FEATURE_FLAGS_TEMPLATE.expand(project.getId()).toString(); try { final URI featureFlagUri = restTemplate.postForLocation(featureFlagsUri, featureFlag); notNull(featureFlagsUri, "URI of new featureFlag"); return getFeatureFlag(featureFlagUri.toString()); } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to create feature flag: " + featureFlag, e); } } /** * Get feature flag by unique name (aka "key"). * * @param project project, cannot be null * @param featureFlagName name of feature flag, cannot be empty * @return feature flag * @deprecated use {@link FeatureFlagService#getProjectFeatureFlag(Project, String)} */ @Deprecated @SuppressWarnings("deprecation") public ProjectFeatureFlag getFeatureFlag(final Project project, final String featureFlagName) { notNull(project, "project"); notEmpty(featureFlagName, "featureFlagName"); return restTemplate.getForObject(getFeatureFlagUri(project, featureFlagName), ProjectFeatureFlag.class); } /** * Updates existing feature flag. * Note that it doesn't make sense to update any other field than {@link ProjectFeatureFlag#enabled}. * * @param featureFlag updated feature flag * @return updated feature flag * @deprecated use {@link FeatureFlagService#updateProjectFeatureFlag(com.gooddata.featureflag.ProjectFeatureFlag)} */ @Deprecated @SuppressWarnings("deprecation") public ProjectFeatureFlag updateFeatureFlag(final ProjectFeatureFlag featureFlag) { notNull(featureFlag, "featureFlag"); notEmpty(featureFlag.getUri(), "featureFlag"); try { restTemplate.put(featureFlag.getUri(), featureFlag); return getFeatureFlag(featureFlag.getUri()); } catch (GoodDataException | RestClientException e) { throw new GoodDataException("Unable to create feature flag: " + featureFlag, e); } } /** * Deletes existing project feature flag. * * @param featureFlag existing project feature flag with links set properly, cannot be null * @deprecated use {@link FeatureFlagService#deleteFeatureFlag(com.gooddata.featureflag.ProjectFeatureFlag)} */ @Deprecated @SuppressWarnings("deprecation") public void deleteFeatureFlag(ProjectFeatureFlag featureFlag) { notNull(featureFlag, "featureFlag"); notEmpty(featureFlag.getUri(), "featureFlag URI"); try { restTemplate.delete(featureFlag.getUri()); } catch (GoodDataRestException | RestClientException e) { throw new GoodDataException("Unable to delete feature flag=" + featureFlag, e); } } @SuppressWarnings("deprecation") private ProjectFeatureFlag getFeatureFlag(String featureFlagUri) { return restTemplate.getForObject(featureFlagUri, ProjectFeatureFlag.class); } private String getFeatureFlagUri(final Project project, final String featureFlagName) { return FEATURE_FLAG_TEMPLATE.expand(project.getId(), featureFlagName).toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy