org.trustedanalytics.cloud.cc.FeignClient Maven / Gradle / Ivy
/**
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.trustedanalytics.cloud.cc;
import org.trustedanalytics.cloud.cc.api.CcAppEnv;
import org.trustedanalytics.cloud.cc.api.CcAppStatus;
import org.trustedanalytics.cloud.cc.api.CcAppSummary;
import org.trustedanalytics.cloud.cc.api.CcBuildpack;
import org.trustedanalytics.cloud.cc.api.CcExtendedService;
import org.trustedanalytics.cloud.cc.api.CcExtendedServiceInstance;
import org.trustedanalytics.cloud.cc.api.CcExtendedServicePlan;
import org.trustedanalytics.cloud.cc.api.CcMemoryUsage;
import org.trustedanalytics.cloud.cc.api.CcNewServiceBinding;
import org.trustedanalytics.cloud.cc.api.CcNewServiceInstance;
import org.trustedanalytics.cloud.cc.api.CcNewServiceKey;
import org.trustedanalytics.cloud.cc.api.CcOperations;
import org.trustedanalytics.cloud.cc.api.CcOrg;
import org.trustedanalytics.cloud.cc.api.CcOrgPermission;
import org.trustedanalytics.cloud.cc.api.CcOrgSummary;
import org.trustedanalytics.cloud.cc.api.CcPlanVisibility;
import org.trustedanalytics.cloud.cc.api.CcQuota;
import org.trustedanalytics.cloud.cc.api.CcServiceBinding;
import org.trustedanalytics.cloud.cc.api.CcServiceBindingList;
import org.trustedanalytics.cloud.cc.api.CcServiceKey;
import org.trustedanalytics.cloud.cc.api.CcSpace;
import org.trustedanalytics.cloud.cc.api.CcSummary;
import org.trustedanalytics.cloud.cc.api.Page;
import org.trustedanalytics.cloud.cc.api.customizations.CompositeErrorDecoder;
import org.trustedanalytics.cloud.cc.api.customizations.FeignErrorDecoderHandler;
import org.trustedanalytics.cloud.cc.api.loggers.ScramblingSlf4jLogger;
import org.trustedanalytics.cloud.cc.api.manageusers.CcOrgUser;
import org.trustedanalytics.cloud.cc.api.manageusers.CcOrgUsersList;
import org.trustedanalytics.cloud.cc.api.manageusers.CcUser;
import org.trustedanalytics.cloud.cc.api.manageusers.Role;
import org.trustedanalytics.cloud.cc.api.manageusers.User;
import org.trustedanalytics.cloud.cc.api.queries.FilterQuery;
import org.trustedanalytics.cloud.cc.api.resources.CcApplicationResource;
import org.trustedanalytics.cloud.cc.api.resources.CcBuildpacksResource;
import org.trustedanalytics.cloud.cc.api.resources.CcOrganizationResource;
import org.trustedanalytics.cloud.cc.api.resources.CcQuotaResource;
import org.trustedanalytics.cloud.cc.api.resources.CcServiceBindingResource;
import org.trustedanalytics.cloud.cc.api.resources.CcServiceResource;
import org.trustedanalytics.cloud.cc.api.resources.CcSpaceResource;
import org.trustedanalytics.cloud.cc.api.resources.CcUserResource;
import org.trustedanalytics.cloud.cc.api.utils.UuidJsonDeserializer;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy;
import com.google.common.collect.ImmutableMap;
import feign.Feign;
import feign.Feign.Builder;
import feign.Request;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.apache.commons.lang.StringUtils;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import rx.Observable;
public class FeignClient implements CcOperations {
private static final Map ROLE_MAP = ImmutableMap.builder()
.put(Role.MANAGERS, "managed_spaces")
.put(Role.AUDITORS, "audited_spaces")
.put(Role.DEVELOPERS,"spaces")
.build();
private static final int CONNECT_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(30);
private static final int READ_TIMEOUT = (int) TimeUnit.MINUTES.toMillis(5);
// We do a lot of delegation here because of https://github.com/Netflix/feign/issues/133
private final CcApplicationResource applicationResource;
private final CcOrganizationResource organizationResource;
private final CcServiceResource serviceResource;
private final CcServiceBindingResource serviceBindingResource;
private final CcSpaceResource spaceResource;
private final CcUserResource userResource;
private final CcBuildpacksResource buildpackResource;
private final CcQuotaResource quotaResource;
/**
* Creates client applying default configuration
* @param url endpoint url
*/
public FeignClient(String url) {
this(url, Function.identity());
}
/**
* Creates client applying default configuration and then customizations. Example:
*
* {@code
* new FeignClient(apiUrl, builder -> builder.requestInterceptor(template ->
* template.header("Authorization", "bearer " + token)));
* }
*
* @param url endpoint url
* @param customizations custom configuration that should be applied after defaults
*/
public FeignClient(String url, Function customizations) {
Objects.requireNonNull(url);
Objects.requireNonNull(customizations);
final ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setPropertyNamingStrategy(new LowerCaseWithUnderscoresStrategy());
// avoid duplication of slashes
final String targetUrl = StringUtils.removeEnd(url, "/");
// first applies defaults and then custom configuration
final Builder builder = customizations.apply(Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder(mapper))
.options(new Request.Options(CONNECT_TIMEOUT, READ_TIMEOUT))
.logger(new ScramblingSlf4jLogger(FeignClient.class))
.logLevel(feign.Logger.Level.BASIC)
.errorDecoder(new CompositeErrorDecoder(new FeignErrorDecoderHandler("description"))));
this.applicationResource = builder.target(CcApplicationResource.class, targetUrl);
this.organizationResource = builder.target(CcOrganizationResource.class, targetUrl);
this.serviceResource = builder.target(CcServiceResource.class, targetUrl);
this.serviceBindingResource = builder.target(CcServiceBindingResource.class, targetUrl);
this.spaceResource = builder.target(CcSpaceResource.class, targetUrl);
this.userResource = builder.target(CcUserResource.class, targetUrl);
this.buildpackResource = builder.target(CcBuildpacksResource.class, targetUrl);
this.quotaResource = builder.target(CcQuotaResource.class, targetUrl);
}
@Override public CcAppSummary getAppSummary(UUID app) {
return applicationResource.getAppSummary(app);
}
@Override public void restageApp(UUID appGuid) {
applicationResource.restageApp(appGuid);
}
@Override public CcServiceBindingList getAppBindings(UUID app) {
return applicationResource.getAppBindings(app);
}
@Override
public CcServiceBindingList getAppBindings(UUID app, FilterQuery query) {
return applicationResource.getAppBindings(app, query);
}
@Override
public void deleteApp(UUID app) {
applicationResource.deleteApp(app);
}
@Override public CcServiceBinding createServiceBinding(CcNewServiceBinding ccNewServiceBinding) {
return serviceBindingResource.createServiceBinding(ccNewServiceBinding);
}
@Override public void deleteServiceBinding(UUID bindingGuid) {
serviceBindingResource.deleteServiceBinding(bindingGuid);
}
@Override public void createUser(UUID userGuid) {
userResource.createUser(userGuid);
}
@Override public UUID createOrganization(String orgName) {
return organizationResource.createOrganization(orgName).getGuid();
}
@Override public UUID createSpace(UUID orgGuid, String name) {
return spaceResource.createSpace(orgGuid, name).getGuid();
}
@Override public void assignUserToOrganization(UUID userGuid, UUID orgGuid) {
organizationResource.associateUserWithOrganization(orgGuid, userGuid);
organizationResource.associateManagerWithOrganization(orgGuid, userGuid);
}
@Override public void assignUserToSpace(UUID userGuid, UUID spaceGuid) {
spaceResource.associateDeveloperWithSpace(spaceGuid, userGuid);
spaceResource.associateManagerWithSpace(spaceGuid, userGuid);
}
@Override public Observable getOrg(UUID orgUUID) {
return Observable.defer(() -> Observable.just(organizationResource.getOrganization(orgUUID)));
}
@Override
public Observable getOrgs() {
return Observable.defer(() -> concatPages(organizationResource.getOrgs(), organizationResource::getOrgs));
}
@Override
public Observable getSpaces() {
return Observable.defer(() -> concatPages(spaceResource.getSpaces(), spaceResource::getSpaces));
}
private Observable concatPages(Page page, Function> more) {
if (page.getNextUrl() == null) {
return Observable.from(page.getResources());
} else {
final URI nextUrl = URI.create(page.getNextUrl());
return Observable.from(page.getResources())
.concatWith(Observable.defer(() -> concatPages(more.apply(nextUrl), more)));
}
}
@Override
public Observable getSpace(UUID spaceId) {
return Observable.defer(() -> Observable.just(spaceResource.getSpace(spaceId)));
}
@Override public Observable getSpaces(UUID org) {
return Observable.defer(() -> concatPages(organizationResource.getSpacesForOrganization(org), spaceResource::getSpaces));
}
@Override public Collection getManagedOrganizations(UUID user) {
return userResource.getManagedOrganizations(user).getOrgs();
}
@Override public Collection getAuditedOrganizations(UUID user) {
return userResource.getAuditedOrganizations(user).getOrgs();
}
@Override public Collection getBillingManagedOrganizations(UUID user) {
return userResource.getBillingManagedOrganizations(user).getOrgs();
}
@Override public void renameOrg(UUID orgId, String name) {
organizationResource.updateOrganization(orgId, name);
}
@Override public void deleteOrg(UUID orgGuid) {
organizationResource.deleteOrganization(orgGuid);
}
@Override
public void deleteSpace(UUID spaceGuid) {
spaceResource.removeSpace(spaceGuid);
}
@Override
public Collection getUsersSpaces(UUID userGuid, Role role, FilterQuery filterQuery) {
return userResource.getUserSpaces(userGuid, ROLE_MAP.get(role), filterQuery).getSpaces();
}
@Override
public Observable getExtendedServices() {
return Observable.defer(() -> concatPages(serviceResource.getServices(), serviceResource::getServices));
}
@Override
public Observable getExtendedServices(FilterQuery filterQuery) {
return Observable.defer(() -> concatPages(serviceResource.getServices(filterQuery), serviceResource::getServices));
}
@Override
public Observable getExtendedServiceInstances() {
return Observable.defer(() -> concatPages(serviceResource.getExtendedServiceInstances(),
serviceResource::getExtendedServiceInstances));
}
@Override
public Observable getExtendedServiceInstances(FilterQuery filterQuery) {
return Observable.defer(() -> concatPages(serviceResource.getExtendedServiceInstances(filterQuery),
serviceResource::getExtendedServiceInstances));
}
@Override
public Observable getExtendedServiceInstances(int depth) {
return Observable.defer(() -> concatPages(serviceResource.getExtendedServiceInstances(depth),
serviceResource::getExtendedServiceInstances));
}
@Override
public Observable getExtendedServiceInstances(FilterQuery filterQuery, int depth) {
return Observable.defer(() -> concatPages(serviceResource.getExtendedServiceInstances(filterQuery, depth),
serviceResource::getExtendedServiceInstances));
}
@Override
public Observable getExtendedServicePlans(UUID serviceGuid) {
return Observable.defer(() -> concatPages(serviceResource.getExtendedServicePlans(serviceGuid),
serviceResource::getExtendedServicePlans));
}
@Override
public Observable getExtendedServicePlan(UUID servicePlanGuid) {
return Observable.defer(() -> Observable.just(serviceResource.getExtendedServicePlan(servicePlanGuid)));
}
@Override
public Observable getServices(UUID spaceGuid) {
return Observable.defer(() -> concatPages(spaceResource.getServices(spaceGuid),
spaceResource::getServices));
}
@Override
public Observable getOrganizationServices(UUID orgGuid) {
return Observable.defer(() -> concatPages(organizationResource.getOrganizationServices(orgGuid),
organizationResource::getOrganizationServices));
}
@Override public Observable getService(UUID serviceGuid) {
return Observable.defer(() -> Observable.just(serviceResource.getService(serviceGuid)));
}
@Override
public CcServiceBindingList getServiceBindings(FilterQuery filterQuery) {
return serviceBindingResource.getServiceBindings(filterQuery);
}
@Override public Observable getServiceKeys() {
return Observable.defer(() -> concatPages(serviceResource.getServiceKeys(),
serviceResource::getServiceKeys));
}
@Override public Observable createServiceKey(CcNewServiceKey serviceKey) {
return Observable.defer(() -> Observable.just(serviceResource.createServiceKey(serviceKey)));
}
@Override
public void deleteServiceKey(UUID keyGuid) {
serviceResource.deleteServiceKey(keyGuid);
}
@Override
public Observable setExtendedServicePlanVisibility(UUID servicePlanGuid, UUID organizationGuid) {
return Observable.defer(() -> Observable.just(serviceResource.setServicePlanVisibility(servicePlanGuid, organizationGuid)));
}
@Override
public Observable getExtendedServicePlanVisibility(FilterQuery filterQuery) {
return Observable.defer(() -> concatPages(serviceResource.getServicePlanVisibility(filterQuery),
serviceResource::getServicePlanVisibility));
}
@Override public Observable getServiceInstance(UUID instanceGuid) {
return Observable.defer(() -> Observable.just(serviceResource.getServiceInstance(instanceGuid)));
}
@Override public Observable createServiceInstance(CcNewServiceInstance serviceInstance) {
return Observable.defer(() -> Observable.just(serviceResource.createServiceInstance(serviceInstance)));
}
@Override public void deleteServiceInstance(UUID instanceGuid) {
serviceResource.deleteServiceInstance(instanceGuid);
}
@Override public CcSummary getSpaceSummary(UUID spaceGuid) {
return spaceResource.getSpaceSummary(spaceGuid);
}
@Override public Collection getUserOrgs(UUID userGuid) {
return userResource.getUserOrganizations(userGuid).getOrgs();
}
@Override public Collection getUserPermissions(UUID user, Collection orgsFilter) {
Collection orgs = userResource.getUserOrganizations(user).getOrgs();
if(!orgsFilter.isEmpty()) {
orgs.removeIf(ccOrg -> !orgsFilter.contains(ccOrg.getGuid()));
}
Collection managedOrganizations = getManagedOrganizations(user);
Collection auditedOrganizations = getAuditedOrganizations(user);
Collection billingManagedOrganizations = getBillingManagedOrganizations(user);
Collection permissions = new ArrayList<>();
orgs.forEach(org -> {
boolean isManager = managedOrganizations.contains(org);
boolean isAuditor = auditedOrganizations.contains(org);
boolean isBillingManager = billingManagedOrganizations.contains(org);
permissions.add(new CcOrgPermission(org, isManager, isAuditor, isBillingManager));
});
return permissions;
}
@Override public Collection getOrgUsers(UUID orgGuid, Role role) {
return toUsers(Observable.defer(() -> concatPages(organizationResource.getOrganizationUsers(orgGuid,role.getValue()),
organizationResource::getOrganizationUsers)), role);
}
@Override public Collection getSpaceUsers(UUID spaceGuid, Role role) {
return toUsers(spaceResource.getSpaceUsers(spaceGuid, role.getValue()), role);
}
@Override
public Observable getSpaceUsersWithRoles(UUID spaceGuid) {
return Observable.defer(() -> concatPages(spaceResource.getSpaceUsersWithRoles(spaceGuid),
spaceResource::getSpaceUsersWithRoles))
.map(ccOrgUser -> new User(ccOrgUser.getUsername(), ccOrgUser.getGuid(), ccOrgUser.getRoles()));
}
@Override
public Observable getOrgUsersWithRoles(UUID orgGuid) {
return Observable.defer(() -> concatPages(organizationResource.getOrganizationUsersWithRoles(orgGuid),
organizationResource::getOrganizationUsersWithRoles))
.map(ccOrgUser -> new User(ccOrgUser.getUsername(), ccOrgUser.getGuid(), ccOrgUser.getRoles()));
}
@Override public void assignOrgRole(UUID userGuid, UUID orgGuid, Role role) {
organizationResource.associateUserWithOrganizationRole(orgGuid, userGuid, role.getValue());
}
@Override public void assignSpaceRole(UUID userGuid, UUID orgGuid, Role role) {
spaceResource.associateUserWithSpaceRole(orgGuid, userGuid, role.getValue());
}
@Override
public void deleteUser(UUID guid) {
userResource.deleteUser(guid);
}
@Override public void revokeOrgRole(UUID userGuid, UUID orgId, Role role) {
organizationResource.removeOrganizationRoleFromUser(orgId, userGuid, role.getValue());
}
@Override public void revokeSpaceRole(UUID userGuid, UUID spaceId, Role role) {
spaceResource.removeSpaceRoleFromUser(spaceId, userGuid, role.getValue());
}
private Collection toUsers(CcOrgUsersList ccUsers, Role role) {
return ccUsers.getUsers().stream()
.map(ccUser -> new User(ccUser.getUsername(), ccUser.getGuid(), role))
.collect(Collectors.toList());
}
private Collection toUsers(Observable ccUsers, Role role) {
return ccUsers.map(ccUser -> new User(ccUser.getUsername(), ccUser.getGuid(), role)).toList().toBlocking().first();
}
@Override
public void switchApp(UUID app, CcAppStatus appStatus) {
applicationResource.switchApp(app, appStatus);
}
@Override public Observable getAppEnv(UUID appUUID) {
return Observable.defer(() -> Observable.just(new CcAppEnv(applicationResource.getAppEnv(appUUID))));
}
@Override public Observable getMemoryUsage(UUID orgGuid) {
return Observable.defer(() -> Observable.just(organizationResource.getMemoryUsage(orgGuid)));
}
@Override public Observable getQuota() {
return Observable.defer(() -> concatPages(quotaResource.getQuota(),
quotaResource::getQuota));
}
@Override
public Observable getBuildpacks() {
return Observable.defer(() -> concatPages(buildpackResource.getBuildpacks(),
buildpackResource::getBuildpacks));
}
@Override
public Observable getOrgSummary(UUID orgGuid) {
return Observable.defer(() -> Observable.just(organizationResource.getOrganizationSummary(orgGuid)));
}
@Override
public Observable getUsers() {
return Observable.defer(() -> concatPages(userResource.getUsers(),
userResource::getUsers)
.filter(user -> !user.getMetadata().getGuid().equals(UuidJsonDeserializer.ARTIFICIAL_USER_GUID)));
}
@Override
public Observable getUsersCount() {
return Observable.defer(() -> Observable.just(userResource.getUsersCount().getTotalResults()));
}
@Override
public Observable getServicesCount() {
return Observable.defer(() -> Observable.just(serviceResource.getServices().getTotalResults()));
}
@Override
public Observable getServiceInstancesCount() {
return Observable.defer(() -> Observable.just(serviceResource.getExtendedServiceInstances().getTotalResults()));
}
@Override
public Observable getApplicationsCount() {
return Observable.defer(() -> Observable.just(applicationResource.getApplications().getTotalResults()));
}
@Override
public Observable getBuildpacksCount() {
return Observable.defer(() -> Observable.just(buildpackResource.getBuildpacks().getTotalResults()));
}
@Override
public Observable getSpacesCount() {
return Observable.defer(() -> Observable.just(spaceResource.getSpaces().getTotalResults()));
}
@Override
public Observable getOrgsCount() {
return Observable.defer(() -> Observable.just(organizationResource.getOrgs().getTotalResults()));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy