Skip to content

Commit

Permalink
feat(cf): update space and org services to use v3 endpoints (#5039)
Browse files Browse the repository at this point in the history
  • Loading branch information
zachsmith1 committed Oct 26, 2020
1 parent 522ffba commit cdca4de
Show file tree
Hide file tree
Showing 25 changed files with 262 additions and 201 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@

package com.netflix.spinnaker.clouddriver.cloudfoundry.client;

import static com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClientUtils.collectPages;
import static com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClientUtils.safelyCall;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.api.OrganizationService;
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundryOrganization;
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundrySpace;
import java.util.Collections;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
Expand All @@ -48,8 +48,8 @@ public CloudFoundryOrganization load(@Nonnull String guid)
.map(
org ->
CloudFoundryOrganization.builder()
.id(org.getMetadata().getGuid())
.name(org.getEntity().getName())
.id(org.getGuid())
.name(org.getName())
.build())
.orElseThrow(ResourceNotFoundException::new);
}
Expand All @@ -67,58 +67,11 @@ public CloudFoundryOrganization findById(String orgId) throws CloudFoundryApiExc

public Optional<CloudFoundryOrganization> findByName(String orgName)
throws CloudFoundryApiException {
return safelyCall(() -> api.all(null, Collections.singletonList("name:" + orgName)))
.flatMap(
page ->
page.getResources().stream()
.findAny()
.map(
org ->
CloudFoundryOrganization.builder()
.id(org.getMetadata().getGuid())
.name(org.getEntity().getName())
.build()));
}

public Optional<CloudFoundrySpace> findSpaceByRegion(String region) {
CloudFoundrySpace space = CloudFoundrySpace.fromRegion(region);

// fully populates the space guid which is what Cloud Foundry's API expects as an input, not the
// name.
Optional<CloudFoundryOrganization> organization = findByName(space.getOrganization().getName());

Optional<CloudFoundrySpace> spaceOptional =
organization.map(org -> findSpaceByName(org, space.getName()));

spaceOptional.ifPresent(
spaceCase -> {
if (!(space.getName().equals(spaceCase.getName())
&& space.getOrganization().getName().equals(spaceCase.getOrganization().getName()))) {
throw new CloudFoundryApiException("Org or Space name not in correct case");
}
});

return spaceOptional;
}

@Nullable
private CloudFoundrySpace findSpaceByName(
CloudFoundryOrganization organization, String spaceName) {
return safelyCall(
() ->
api.getSpaceByName(
organization.getId(), null, Collections.singletonList("name:" + spaceName)))
.flatMap(
page ->
page.getResources().stream()
.findAny()
.map(
resource ->
CloudFoundrySpace.builder()
.id(resource.getMetadata().getGuid())
.name(resource.getEntity().getName())
.organization(organization)
.build()))
.orElse(null);
return collectPages("organizations", page -> api.all(page, Collections.singletonList(orgName)))
.stream()
.findAny()
.map(
org ->
CloudFoundryOrganization.builder().id(org.getGuid()).name(org.getName()).build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ private List<CloudFoundryServicePlan> findAllServicePlansByServiceName(String se
}

public List<CloudFoundryService> findAllServicesByRegion(String region) {
return orgs.findSpaceByRegion(region)
return spaces
.findSpaceByRegion(region)
.map(
space -> {
List<Resource<Service>> services =
Expand All @@ -131,7 +132,8 @@ public List<CloudFoundryService> findAllServicesByRegion(String region) {
CloudFoundryServiceInstance getOsbServiceInstanceByRegion(
String region, String serviceInstanceName) {
CloudFoundrySpace space =
orgs.findSpaceByRegion(region)
spaces
.findSpaceByRegion(region)
.orElseThrow(() -> new CloudFoundryApiException("Cannot find region '" + region + "'"));
return Optional.ofNullable(getOsbServiceInstance(space, serviceInstanceName))
.orElseThrow(
Expand Down Expand Up @@ -166,7 +168,8 @@ private Set<CloudFoundrySpace> vetSharingOfServicesArgumentsAndGetSharingSpaces(
throw new CloudFoundryApiException(
"Cannot specify 'org > space' as any of the " + gerund + " regions");
}
return orgs.findSpaceByRegion(r)
return spaces
.findSpaceByRegion(r)
.orElseThrow(
() ->
new CloudFoundryApiException(
Expand Down Expand Up @@ -316,7 +319,8 @@ public ServiceInstanceResponse unshareServiceInstance(
@Nullable
public CloudFoundryServiceInstance getServiceInstance(String region, String serviceInstanceName) {
CloudFoundrySpace space =
orgs.findSpaceByRegion(region)
spaces
.findSpaceByRegion(region)
.orElseThrow(() -> new CloudFoundryApiException("Cannot find region '" + region + "'"));
Supplier<CloudFoundryServiceInstance> si =
() -> Optional.ofNullable(getOsbServiceInstance(space, serviceInstanceName)).orElse(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@

package com.netflix.spinnaker.clouddriver.cloudfoundry.client;

import static com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClientUtils.collectPageResources;
import static com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClientUtils.safelyCall;
import static com.netflix.spinnaker.clouddriver.cloudfoundry.client.CloudFoundryClientUtils.*;
import static java.util.stream.Collectors.toList;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.api.SpaceService;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v2.*;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v3.Space;
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundryOrganization;
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundryServiceInstance;
import com.netflix.spinnaker.clouddriver.cloudfoundry.model.CloudFoundrySpace;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -66,7 +66,7 @@ public CloudFoundrySpace findById(String guid) throws CloudFoundryApiException {
}

public List<CloudFoundrySpace> all() throws CloudFoundryApiException {
return collectPageResources("spaces", pg -> api.all(pg, null)).stream()
return collectPages("spaces", page -> api.all(page, null, null)).stream()
.map(this::map)
.collect(toList());
}
Expand All @@ -93,9 +93,14 @@ public CloudFoundryServiceInstance getServiceInstanceById(
@Nullable
public CloudFoundrySpace findByName(String orgId, String spaceName)
throws CloudFoundryApiException {
return safelyCall(
() -> api.all(null, Arrays.asList("name:" + spaceName, "organization_guid:" + orgId)))
.flatMap(page -> page.getResources().stream().findAny().map(this::map))
return collectPages(
"spaces",
page ->
api.all(
page, Collections.singletonList(spaceName), Collections.singletonList(orgId)))
.stream()
.findAny()
.map(this::map)
.orElse(null);
}

Expand All @@ -106,11 +111,53 @@ public CloudFoundryServiceInstance getServiceInstanceByNameAndSpace(
.orElse(null);
}

private CloudFoundrySpace map(Resource<Space> res) throws CloudFoundryApiException {
private CloudFoundrySpace map(Space space) throws CloudFoundryApiException {
return CloudFoundrySpace.builder()
.id(res.getMetadata().getGuid())
.name(res.getEntity().getName())
.organization(organizations.findById(res.getEntity().getOrganizationGuid()))
.id(space.getGuid())
.name(space.getName())
.organization(
organizations.findById(
space.getRelationships().get("organization").getData().getGuid()))
.build();
}

public Optional<CloudFoundrySpace> findSpaceByRegion(String region) {
CloudFoundrySpace space = CloudFoundrySpace.fromRegion(region);

CloudFoundryOrganization organization =
organizations
.findByName(space.getOrganization().getName())
.orElseThrow(
() ->
new CloudFoundryApiException(
"Unable to find organization: " + space.getOrganization().getName()));

Optional<CloudFoundrySpace> spaceOptional =
collectPages(
"spaces",
page ->
api.all(
page,
Collections.singletonList(space.getName()),
Collections.singletonList(organization.getId())))
.stream()
.findAny()
.map(
s ->
CloudFoundrySpace.builder()
.id(s.getGuid())
.name(s.getName())
.organization(organization)
.build());

spaceOptional.ifPresent(
spaceCase -> {
if (!(space.getName().equals(spaceCase.getName())
&& space.getOrganization().getName().equals(spaceCase.getOrganization().getName()))) {
throw new CloudFoundryApiException("Org or Space name not in correct case");
}
});

return spaceOptional;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,17 @@

package com.netflix.spinnaker.clouddriver.cloudfoundry.client.api;

import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v2.Organization;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v2.Page;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v2.Resource;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v2.Space;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v3.Organization;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v3.Pagination;
import java.util.List;
import retrofit.http.GET;
import retrofit.http.Path;
import retrofit.http.Query;

public interface OrganizationService {
@GET("/v2/organizations")
Page<Organization> all(@Query("page") Integer page, @Query("q") List<String> query);
@GET("/v3/organizations")
Pagination<Organization> all(@Query("page") Integer page, @Query("names") List<String> orgNames);

@GET("/v2/organizations/{guid}")
Resource<Organization> findById(@Path("guid") String guid);

@GET("/v2/organizations/{guid}/spaces")
Page<Space> getSpaceByName(
@Path("guid") String guid, @Query("page") Integer page, @Query("q") List<String> query);
@GET("/v3/organizations/{guid}")
Organization findById(@Path("guid") String guid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,22 @@
package com.netflix.spinnaker.clouddriver.cloudfoundry.client.api;

import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v2.*;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v3.Pagination;
import com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v3.Space;
import java.util.List;
import retrofit.http.GET;
import retrofit.http.Path;
import retrofit.http.Query;

public interface SpaceService {
@GET("/v2/spaces")
Page<Space> all(@Query("page") Integer page, @Query("q") List<String> query);
@GET("/v3/spaces")
Pagination<Space> all(
@Query("page") Integer page,
@Query("names") List<String> names,
@Query("organization_guids") List<String> orgGuids);

@GET("/v2/spaces/{guid}")
Resource<Space> findById(@Path("guid") String guid);
@GET("/v3/spaces/{guid}")
Space findById(@Path("guid") String guid);

@GET("/v2/spaces/{guid}/service_instances")
Page<ServiceInstance> getServiceInstancesById(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2020 Armory, Inc.
*
* 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 com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v3;

import java.util.Map;
import lombok.Data;

@Data
public class Organization {
private String name;
private String guid;
private Map<String, Link> links;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2020 Armory, Inc.
*
* 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 com.netflix.spinnaker.clouddriver.cloudfoundry.client.model.v3;

import java.util.Map;
import lombok.Data;

@Data
public class Space {
private String guid;
private String name;
private Map<String, ToOneRelationship> relationships;
private Map<String, Link> links;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public abstract class AbstractCloudFoundryAtomicOperationConverter
extends AbstractAtomicOperationsCredentialsConverter<CloudFoundryCredentials> {

protected Optional<CloudFoundrySpace> findSpace(String region, CloudFoundryClient client) {
return client.getOrganizations().findSpaceByRegion(region);
return client.getSpaces().findSpaceByRegion(region);
}

protected CloudFoundryClient getClient(Map<?, ?> input) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public OnDemandResult handle(ProviderCache providerCache, Map<String, ?> data) {
return null;
}

CloudFoundrySpace space = getClient().getOrganizations().findSpaceByRegion(region).orElse(null);
CloudFoundrySpace space = getClient().getSpaces().findSpaceByRegion(region).orElse(null);
if (space == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ public OnDemandResult handle(ProviderCache providerCache, Map<String, ?> data) {
return null;
}

CloudFoundrySpace space =
this.getClient().getOrganizations().findSpaceByRegion(region).orElse(null);
CloudFoundrySpace space = this.getClient().getSpaces().findSpaceByRegion(region).orElse(null);
if (space == null) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public CacheResult loadData(ProviderCache providerCache) {
String accountName = getAccountName();
log.info("Caching all spaces in Cloud Foundry account " + accountName);

List<CloudFoundrySpace> spaces = getCredentials().getSpacesLive();
List<CloudFoundrySpace> spaces = this.getClient().getSpaces().all();

Map<String, Collection<CacheData>> results =
ImmutableMap.of(
Expand Down
Loading

0 comments on commit cdca4de

Please sign in to comment.