Skip to content

Commit b8fb802

Browse files
DT-1130: API to return resources created by a billing profile (#1880)
* Add API to return all resources linked to a billing profile * migrate profile controller test to use WebMvcTest
1 parent 1baa163 commit b8fb802

File tree

10 files changed

+271
-109
lines changed

10 files changed

+271
-109
lines changed

build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ dependencies {
214214

215215
implementation 'com.squareup.okhttp3:okhttp'
216216
implementation 'org.springframework.boot:spring-boot-starter-actuator'
217+
implementation 'org.springframework.hateoas:spring-hateoas'
217218
implementation 'io.micrometer:micrometer-registry-prometheus'
218219

219220
implementation 'com.fasterxml.jackson.core:jackson-core'

src/main/java/bio/terra/app/configuration/ApplicationConfiguration.java

+2
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ public NamedParameterJdbcTemplate synapseJdbcTemplate(
389389
return new NamedParameterJdbcTemplate(ds);
390390
}
391391

392+
// Use Primary to fix an issue with unqualified ObjectMapper injections in spring-hateoas.
393+
@Primary
392394
@Bean("objectMapper")
393395
public ObjectMapper objectMapper() {
394396
return new ObjectMapper()

src/main/java/bio/terra/service/auth/iam/IamAction.java

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public enum IamAction {
4848
// billing profiles
4949
UPDATE_BILLING_ACCOUNT,
5050
LINK,
51+
READ_SPEND_REPORT,
5152
// journal
5253
VIEW_JOURNAL,
5354
// lock/unlock resources

src/main/java/bio/terra/service/profile/ProfileApiController.java

+11-15
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import bio.terra.model.BillingProfileRequestModel;
1212
import bio.terra.model.BillingProfileUpdateModel;
1313
import bio.terra.model.EnumerateBillingProfileModel;
14+
import bio.terra.model.EnumerateBillingProfileResourcesModel;
1415
import bio.terra.model.JobModel;
1516
import bio.terra.model.PolicyMemberRequest;
1617
import bio.terra.model.PolicyModel;
@@ -20,13 +21,11 @@
2021
import bio.terra.service.auth.iam.IamService;
2122
import bio.terra.service.auth.iam.PolicyMemberValidator;
2223
import bio.terra.service.job.JobService;
23-
import com.fasterxml.jackson.databind.ObjectMapper;
2424
import io.swagger.annotations.Api;
2525
import jakarta.servlet.http.HttpServletRequest;
2626
import jakarta.validation.Valid;
2727
import java.util.Collections;
2828
import java.util.List;
29-
import java.util.Optional;
3029
import java.util.UUID;
3130
import org.springframework.beans.factory.annotation.Autowired;
3231
import org.springframework.http.HttpStatus;
@@ -42,7 +41,6 @@
4241
@Api(tags = {"profiles"})
4342
public class ProfileApiController implements ProfilesApi {
4443

45-
private final ObjectMapper objectMapper;
4644
private final HttpServletRequest request;
4745
private final ProfileService profileService;
4846
private final ProfileRequestValidator billingProfileRequestValidator;
@@ -56,7 +54,6 @@ public class ProfileApiController implements ProfilesApi {
5654

5755
@Autowired
5856
public ProfileApiController(
59-
ObjectMapper objectMapper,
6057
HttpServletRequest request,
6158
ProfileService profileService,
6259
ProfileRequestValidator billingProfileRequestValidator,
@@ -66,7 +63,6 @@ public ProfileApiController(
6663
AuthenticatedUserRequestFactory authenticatedUserRequestFactory,
6764
IamService iamService,
6865
ApplicationConfiguration applicationConfiguration) {
69-
this.objectMapper = objectMapper;
7066
this.request = request;
7167
this.profileService = profileService;
7268
this.billingProfileRequestValidator = billingProfileRequestValidator;
@@ -78,16 +74,6 @@ public ProfileApiController(
7874
this.applicationConfiguration = applicationConfiguration;
7975
}
8076

81-
@Override
82-
public Optional<ObjectMapper> getObjectMapper() {
83-
return Optional.ofNullable(objectMapper);
84-
}
85-
86-
@Override
87-
public Optional<HttpServletRequest> getRequest() {
88-
return Optional.ofNullable(request);
89-
}
90-
9177
@InitBinder
9278
protected void initBinder(final WebDataBinder binder) {
9379
binder.addValidators(profileUpdateRequestValidator);
@@ -199,4 +185,14 @@ private void verifyAuthorization(
199185
// Verify permissions
200186
iamService.verifyAuthorization(userReq, resourceType, resourceId, action);
201187
}
188+
189+
@Override
190+
public ResponseEntity<EnumerateBillingProfileResourcesModel> getProfileResources(UUID id) {
191+
AuthenticatedUserRequest user = authenticatedUserRequestFactory.from(request);
192+
var resources =
193+
profileService.getProfileResources(id, user).stream()
194+
.map(ProfileOwnedResource::toModel)
195+
.toList();
196+
return ResponseEntity.ok(new EnumerateBillingProfileResourcesModel().items(resources));
197+
}
202198
}

src/main/java/bio/terra/service/profile/ProfileOwnedResource.java

+13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package bio.terra.service.profile;
22

3+
import bio.terra.model.ProfileOwnedResourceModel;
34
import java.time.Instant;
45
import java.util.UUID;
56

@@ -9,4 +10,16 @@ public enum Type {
910
DATASET,
1011
SNAPSHOT,
1112
}
13+
14+
public ProfileOwnedResourceModel toModel() {
15+
return new ProfileOwnedResourceModel()
16+
.id(id)
17+
.name(name)
18+
.description(description)
19+
.createdDate(createdDate.toString())
20+
.type(
21+
Type.DATASET == type
22+
? ProfileOwnedResourceModel.TypeEnum.DATASET
23+
: ProfileOwnedResourceModel.TypeEnum.SNAPSHOT);
24+
}
1225
}

src/main/java/bio/terra/service/profile/ProfileService.java

+7
Original file line numberDiff line numberDiff line change
@@ -303,4 +303,11 @@ public void verifyDeployedApplication(
303303
+ "operation");
304304
}
305305
}
306+
307+
public List<ProfileOwnedResource> getProfileResources(
308+
UUID profileId, AuthenticatedUserRequest user) {
309+
iamService.verifyAuthorization(
310+
user, IamResourceType.SPEND_PROFILE, profileId.toString(), IamAction.READ_SPEND_REPORT);
311+
return profileDao.listProfileOwnedResources(profileId);
312+
}
306313
}

src/main/resources/api/data-repository-openapi.yaml

+63
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,42 @@ paths:
520520
schema:
521521
$ref: '#/components/schemas/ErrorModel'
522522

523+
/api/resources/v1/profiles/{id}/resources:
524+
get:
525+
tags:
526+
- profiles
527+
- resources
528+
description: >
529+
Given a profile ID, return the resources associated with that profile.
530+
operationId: getProfileResources
531+
parameters:
532+
- $ref: '#/components/parameters/Id'
533+
responses:
534+
200:
535+
description: List of resources
536+
content:
537+
application/json:
538+
schema:
539+
$ref: '#/components/schemas/EnumerateBillingProfileResourcesModel'
540+
400:
541+
description: Bad request - invalid id, badly formed
542+
content:
543+
application/json:
544+
schema:
545+
$ref: '#/components/schemas/ErrorModel'
546+
403:
547+
description: No permission to retreive resources
548+
content:
549+
application/json:
550+
schema:
551+
$ref: '#/components/schemas/ErrorModel'
552+
404:
553+
description: Not found - profile id does not exist
554+
content:
555+
application/json:
556+
schema:
557+
$ref: '#/components/schemas/ErrorModel'
558+
523559
/api/repository/v1/snapshots:
524560
get:
525561
tags:
@@ -5242,6 +5278,33 @@ components:
52425278
$ref: '#/components/schemas/BillingProfileModel'
52435279
description: >
52445280
The total number of billing profiles available and a page of profiles
5281+
EnumerateBillingProfileResourcesModel:
5282+
type: object
5283+
properties:
5284+
items:
5285+
type: array
5286+
items:
5287+
$ref: '#/components/schemas/ProfileOwnedResourceModel'
5288+
description: >
5289+
The resources created using this billing profile
5290+
ProfileOwnedResourceModel:
5291+
type: object
5292+
properties:
5293+
id:
5294+
$ref: '#/components/schemas/UniqueIdProperty'
5295+
name:
5296+
type: string
5297+
description: Name of the resource
5298+
description:
5299+
type: string
5300+
description: Description of the resource
5301+
createdDate:
5302+
type: string
5303+
description: Date the resource was created
5304+
type:
5305+
type: string
5306+
description: Type of the resource
5307+
enum: [ DATASET, SNAPSHOT ]
52455308
DatasetModel:
52465309
type: object
52475310
properties:

0 commit comments

Comments
 (0)