Skip to content

Commit 0172c89

Browse files
committed
Simplify tenant service GET on /tenants to return all records and
support status=onboarded or status=provisioned for filtering
1 parent 9895257 commit 0172c89

File tree

6 files changed

+34
-213
lines changed

6 files changed

+34
-213
lines changed

resources/saas-boost-private-api.yaml

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ Parameters:
4040
TenantServiceGetAll:
4141
Description: Tenant Service get all tenants Lambda ARN
4242
Type: String
43-
TenantServiceGetProvisioned:
44-
Description: Tenant Service get provisioned tenants Lambda ARN
45-
Type: String
4643
SettingsServiceGetAll:
4744
Description: Settings Service get all settings Lambda ARN
4845
Type: String
@@ -148,12 +145,6 @@ Resources:
148145
RestApiId: !Ref PrivateApi
149146
ParentId: !Ref RootResourceId
150147
PathPart: 'tenants'
151-
TenantServiceProvisionedResource:
152-
Type: AWS::ApiGateway::Resource
153-
Properties:
154-
RestApiId: !Ref PrivateApi
155-
ParentId: !Ref TenantServiceResource
156-
PathPart: 'provisioned'
157148
TenantServiceByIdResource:
158149
Type: AWS::ApiGateway::Resource
159150
Properties:
@@ -264,60 +255,6 @@ Resources:
264255
method.response.header.Access-Control-Allow-Origin: false
265256
method.response.header.Access-Control-Max-Age: false
266257
method.response.header.X-Requested-With: false
267-
TenantServiceProvisionedMethod:
268-
Type: AWS::ApiGateway::Method
269-
Properties:
270-
RestApiId: !Ref PrivateApi
271-
ResourceId: !Ref TenantServiceProvisionedResource
272-
HttpMethod: GET
273-
AuthorizationType: AWS_IAM
274-
Integration:
275-
Type: AWS_PROXY
276-
IntegrationHttpMethod: POST
277-
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${TenantServiceGetProvisioned}/invocations
278-
PassthroughBehavior: WHEN_NO_MATCH
279-
MethodResponses:
280-
- StatusCode: '200'
281-
ResponseModels: {application/json: Empty}
282-
ResponseParameters:
283-
method.response.header.Access-Control-Allow-Origin: false
284-
TenantServiceGetProvisionedLambdaPermission:
285-
Type: AWS::Lambda::Permission
286-
Properties:
287-
Principal: apigateway.amazonaws.com
288-
Action: lambda:InvokeFunction
289-
FunctionName: !Ref TenantServiceGetProvisioned
290-
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${PrivateApi}/*/GET/tenants/provisioned
291-
TenantServiceProvisionedResourceCORS:
292-
Type: AWS::ApiGateway::Method
293-
Properties:
294-
RestApiId: !Ref PrivateApi
295-
ResourceId: !Ref TenantServiceProvisionedResource
296-
HttpMethod: OPTIONS
297-
AuthorizationType: NONE
298-
Integration:
299-
Type: MOCK
300-
PassthroughBehavior: WHEN_NO_MATCH
301-
IntegrationResponses:
302-
- StatusCode: '200'
303-
ResponseTemplates: {application/json: ''}
304-
ResponseParameters:
305-
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
306-
method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
307-
method.response.header.Access-Control-Allow-Origin: "'*'"
308-
method.response.header.Access-Control-Max-Age: "'3600'"
309-
method.response.header.X-Requested-With: "'*'"
310-
RequestTemplates:
311-
application/json: '{"statusCode": 200}'
312-
MethodResponses:
313-
- StatusCode: '200'
314-
ResponseModels: {application/json: Empty}
315-
ResponseParameters:
316-
method.response.header.Access-Control-Allow-Headers: false
317-
method.response.header.Access-Control-Allow-Methods: false
318-
method.response.header.Access-Control-Allow-Origin: false
319-
method.response.header.Access-Control-Max-Age: false
320-
method.response.header.X-Requested-With: false
321258
SettingsServiceResource:
322259
Type: AWS::ApiGateway::Resource
323260
Properties:

resources/saas-boost-public-api.yaml

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,6 @@ Parameters:
7373
TenantServiceGetAll:
7474
Description: Tenant Service get all tenants Lambda ARN
7575
Type: String
76-
TenantServiceGetProvisioned:
77-
Description: Tenant Service get provisioned tenants Lambda ARN
78-
Type: String
7976
TenantServiceById:
8077
Description: Tenant Service get tenant by id Lambda ARN
8178
Type: String
@@ -973,12 +970,6 @@ Resources:
973970
RestApiId: !Ref PublicApi
974971
ParentId: !Ref TenantServiceResource
975972
PathPart: '{id}'
976-
TenantServiceProvisionedResource:
977-
Type: AWS::ApiGateway::Resource
978-
Properties:
979-
RestApiId: !Ref PublicApi
980-
ParentId: !Ref TenantServiceResource
981-
PathPart: 'provisioned'
982973
TenantServiceEnableResource:
983974
Type: AWS::ApiGateway::Resource
984975
Properties:
@@ -1048,63 +1039,6 @@ Resources:
10481039
method.response.header.Access-Control-Allow-Origin: false
10491040
method.response.header.Access-Control-Max-Age: false
10501041
method.response.header.X-Requested-With: false
1051-
TenantServiceProvisionedMethod:
1052-
Type: AWS::ApiGateway::Method
1053-
Properties:
1054-
RestApiId: !Ref PublicApi
1055-
ResourceId: !Ref TenantServiceProvisionedResource
1056-
HttpMethod: GET
1057-
AuthorizationType: COGNITO_USER_POOLS
1058-
AuthorizerId: !Ref CognitoAuthorizer
1059-
AuthorizationScopes:
1060-
- aws.cognito.signin.user.admin
1061-
Integration:
1062-
Type: AWS_PROXY
1063-
IntegrationHttpMethod: POST
1064-
Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${TenantServiceGetProvisioned}/invocations
1065-
PassthroughBehavior: WHEN_NO_MATCH
1066-
MethodResponses:
1067-
- StatusCode: '200'
1068-
ResponseModels: {application/json: Empty}
1069-
ResponseParameters:
1070-
method.response.header.Access-Control-Allow-Origin: false
1071-
TenantServiceGetProvisionedLambdaPermission:
1072-
Type: AWS::Lambda::Permission
1073-
Properties:
1074-
Principal: apigateway.amazonaws.com
1075-
Action: lambda:InvokeFunction
1076-
FunctionName: !Ref TenantServiceGetProvisioned
1077-
SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${PublicApi}/*/GET/tenants/provisioned
1078-
TenantServiceProvisionedResourceCORS:
1079-
Type: AWS::ApiGateway::Method
1080-
Properties:
1081-
RestApiId: !Ref PublicApi
1082-
ResourceId: !Ref TenantServiceProvisionedResource
1083-
HttpMethod: OPTIONS
1084-
AuthorizationType: NONE
1085-
Integration:
1086-
Type: MOCK
1087-
PassthroughBehavior: WHEN_NO_MATCH
1088-
IntegrationResponses:
1089-
- StatusCode: '200'
1090-
ResponseTemplates: {application/json: ''}
1091-
ResponseParameters:
1092-
method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
1093-
method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
1094-
method.response.header.Access-Control-Allow-Origin: "'*'"
1095-
method.response.header.Access-Control-Max-Age: "'3600'"
1096-
method.response.header.X-Requested-With: "'*'"
1097-
RequestTemplates:
1098-
application/json: '{"statusCode": 200}'
1099-
MethodResponses:
1100-
- StatusCode: '200'
1101-
ResponseModels: {application/json: Empty}
1102-
ResponseParameters:
1103-
method.response.header.Access-Control-Allow-Headers: false
1104-
method.response.header.Access-Control-Allow-Methods: false
1105-
method.response.header.Access-Control-Allow-Origin: false
1106-
method.response.header.Access-Control-Max-Age: false
1107-
method.response.header.X-Requested-With: false
11081042
TenantServiceGetByIdMethod:
11091043
Type: AWS::ApiGateway::Method
11101044
Properties:
@@ -1775,8 +1709,6 @@ Resources:
17751709
- SettingsServiceByIdResourceCORS
17761710
- TenantServiceGetAllMethod
17771711
- TenantServiceResourceCORS
1778-
- TenantServiceProvisionedMethod
1779-
- TenantServiceProvisionedResourceCORS
17801712
- TenantServiceGetByIdMethod
17811713
- TenantServiceUpdateMethod
17821714
- TenantServiceDeleteMethod

resources/saas-boost-svc-tenant.yaml

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -159,37 +159,6 @@ Resources:
159159
SAAS_BOOST_ENV: !Ref Environment
160160
SAAS_BOOST_EVENT_BUS: !Ref SaaSBoostEventBus
161161
TENANTS_TABLE: !Ref TenantsTable
162-
TenantServiceGetProvisionedLogs:
163-
Type: AWS::Logs::LogGroup
164-
Properties:
165-
LogGroupName: !Sub /aws/lambda/sb-${Environment}-tenants-get-provisioned
166-
RetentionInDays: 30
167-
TenantServiceGetProvisioned:
168-
Type: AWS::Lambda::Function
169-
Properties:
170-
FunctionName: !Sub sb-${Environment}-tenants-get-provisioned
171-
Role: !GetAtt TenantServiceExecutionRole.Arn
172-
Runtime: java11
173-
Timeout: 300
174-
MemorySize: 1024
175-
Handler: com.amazon.aws.partners.saasfactory.saasboost.TenantService::getProvisionedTenants
176-
Code:
177-
S3Bucket: !Ref SaaSBoostBucket
178-
S3Key: !Sub ${LambdaSourceFolder}/TenantService-lambda.zip
179-
Layers:
180-
- !Ref SaaSBoostUtilsLayer
181-
Environment:
182-
Variables:
183-
SAAS_BOOST_ENV: !Ref Environment
184-
SAAS_BOOST_EVENT_BUS: !Ref SaaSBoostEventBus
185-
TENANTS_TABLE: !Ref TenantsTable
186-
Tags:
187-
- Key: "Application"
188-
Value: "SaaSBoost"
189-
- Key: "Environment"
190-
Value: !Ref Environment
191-
- Key: "BoostService"
192-
Value: "Tenant"
193162
TenantServiceUpdateLogs:
194163
Type: AWS::Logs::LogGroup
195164
Properties:
@@ -406,9 +375,6 @@ Outputs:
406375
TenantServiceGetAllArn:
407376
Description: Tenant Service get all tenants Lambda ARN
408377
Value: !GetAtt TenantServiceGetAll.Arn
409-
TenantServiceGetProvisionedArn:
410-
Description: Tenant Service get provisioned tenants Lambda ARN
411-
Value: !GetAtt TenantServiceGetProvisioned.Arn
412378
TenantServiceInsertArn:
413379
Description: Tenant Service insert new tenant Lambda ARN
414380
Value: !GetAtt TenantServiceInsert.Arn

resources/saas-boost.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,6 @@ Resources:
768768
SettingsServiceSetAppConfig: !GetAtt settings.Outputs.SettingsServiceSetAppConfigArn
769769
SettingsServiceUpdateAppConfig: !GetAtt settings.Outputs.SettingsServiceUpdateAppConfigArn
770770
TenantServiceGetAll: !GetAtt tenant.Outputs.TenantServiceGetAllArn
771-
TenantServiceGetProvisioned: !GetAtt tenant.Outputs.TenantServiceGetProvisionedArn
772771
TenantServiceById: !GetAtt tenant.Outputs.TenantServiceByIdArn
773772
TenantServiceUpdate: !GetAtt tenant.Outputs.TenantServiceUpdateArn
774773
TenantServiceDelete: !GetAtt tenant.Outputs.TenantServiceDeleteArn
@@ -795,7 +794,6 @@ Resources:
795794
TenantServiceById: !GetAtt tenant.Outputs.TenantServiceByIdArn
796795
TenantServiceInsert: !GetAtt tenant.Outputs.TenantServiceInsertArn
797796
TenantServiceGetAll: !GetAtt tenant.Outputs.TenantServiceGetAllArn
798-
TenantServiceGetProvisioned: !GetAtt tenant.Outputs.TenantServiceGetProvisionedArn
799797
SettingsServiceGetAll: !GetAtt settings.Outputs.SettingsServiceGetAllArn
800798
SettingsServiceGetSecret: !GetAtt settings.Outputs.SettingsServiceGetSecretArn
801799
SettingsServiceDeleteAppConfig: !GetAtt settings.Outputs.SettingsServiceDeleteAppConfigArn

services/tenant-service/src/main/java/com/amazon/aws/partners/saasfactory/saasboost/TenantService.java

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,36 +59,23 @@ public APIGatewayProxyResponseEvent getTenants(Map<String, Object> event, Contex
5959
final long startTimeMillis = System.currentTimeMillis();
6060
LOGGER.info("TenantService::getTenants");
6161
//Utils.logRequestEvent(event);
62-
List<Tenant> tenants = dal.getOnboardedTenants();
63-
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent()
64-
.withStatusCode(200)
65-
.withHeaders(CORS)
66-
.withBody(Utils.toJson(tenants));
67-
long totalTimeMillis = System.currentTimeMillis() - startTimeMillis;
68-
LOGGER.info("TenantService::getTenants exec " + totalTimeMillis);
69-
return response;
70-
}
71-
72-
public APIGatewayProxyResponseEvent getProvisionedTenants(Map<String, Object> event, Context context) {
73-
if (Utils.warmup(event)) {
74-
//LOGGER.info("Warming up");
75-
return new APIGatewayProxyResponseEvent().withHeaders(CORS).withStatusCode(200);
76-
}
77-
78-
final long startTimeMillis = System.currentTimeMillis();
79-
LOGGER.info("TenantService::getProvisionedTenants");
80-
//Utils.logRequestEvent(event);
81-
82-
List<Tenant> tenants;
62+
List<Tenant> tenants = new ArrayList<>();
8363
Map<String, String> queryParams = (Map<String, String>) event.get("queryStringParameters");
84-
tenants = dal.getProvisionedTenants();
85-
64+
if (queryParams != null && queryParams.containsKey("status")) {
65+
if ("provisioned".equalsIgnoreCase(queryParams.get("status"))) {
66+
tenants.addAll(dal.getProvisionedTenants());
67+
} else if ("onboarded".equalsIgnoreCase(queryParams.get("status"))) {
68+
tenants.addAll(dal.getOnboardedTenants());
69+
}
70+
} else {
71+
tenants.addAll(dal.getAllTenants());
72+
}
8673
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent()
8774
.withStatusCode(200)
8875
.withHeaders(CORS)
8976
.withBody(Utils.toJson(tenants));
9077
long totalTimeMillis = System.currentTimeMillis() - startTimeMillis;
91-
LOGGER.info("TenantService::getProvisionedTenants exec {}", totalTimeMillis);
78+
LOGGER.info("TenantService::getTenants exec " + totalTimeMillis);
9279
return response;
9380
}
9481

services/tenant-service/src/main/java/com/amazon/aws/partners/saasfactory/saasboost/TenantServiceDAL.java

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import java.time.format.DateTimeParseException;
2727
import java.util.*;
2828
import java.util.stream.Collectors;
29-
import java.util.stream.Stream;
3029

3130
public class TenantServiceDAL {
3231

@@ -46,20 +45,24 @@ public TenantServiceDAL() {
4645
public List<Tenant> getOnboardedTenants() {
4746
final long startTimeMillis = System.currentTimeMillis();
4847
LOGGER.info("TenantServiceDAL::getTenants");
48+
49+
// Get all tenants that have the workload deployed and are ready to use the system
50+
// or who have had the workload deployed and are in an update/deployment cycle
4951
List<Tenant> tenants = new ArrayList<>();
5052
try {
5153
ScanResponse response = ddb.scan(request -> request
5254
.tableName(TENANTS_TABLE)
53-
.filterExpression("attribute_exists(onboarding_status) AND onboarding_status IN (:status1, :status2)")
54-
.expressionAttributeValues(Stream
55-
.of(
56-
new AbstractMap.SimpleEntry<>(":status1", AttributeValue.builder().s("succeeded").build()),
57-
new AbstractMap.SimpleEntry<>(":status2", AttributeValue.builder().s("updated").build())
58-
)
59-
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
60-
)
55+
.filterExpression("attribute_exists(onboarding_status) "
56+
+ "AND onboarding_status IN (:updating, :updated, :deploying, :deployed)")
57+
.expressionAttributeValues(Map.of(
58+
":updating", AttributeValue.builder().s("updating").build(),
59+
":updated", AttributeValue.builder().s("updated").build(),
60+
":deploying", AttributeValue.builder().s("deploying").build(),
61+
":deployed", AttributeValue.builder().s("deployed").build()
62+
))
63+
.build()
6164
);
62-
LOGGER.info("TenantServiceDAL::getTenants returning " + response.items().size() + " onboarded tenants");
65+
LOGGER.info("TenantServiceDAL::getTenants returning {} onboarded tenants", response.items().size());
6366
response.items().forEach(item ->
6467
tenants.add(fromAttributeValueMap(item))
6568
);
@@ -76,22 +79,20 @@ public List<Tenant> getProvisionedTenants() {
7679
final long startTimeMillis = System.currentTimeMillis();
7780
LOGGER.info("TenantServiceDAL::getProvisionedTenants");
7881

79-
// Get all tenants who haven't just started provisioning (created)
80-
// or who had an error during provisioning (failed)
81-
String filter = "attribute_exists(onboarding_status) " +
82-
"AND onboarding_status <> :created " +
83-
"AND onboarding_status <> :failed " +
84-
"AND onboarding_status <> :deleted";
85-
Map<String, AttributeValue> expressions = new HashMap<>();
86-
expressions.put(":created", AttributeValue.builder().s("created").build());
87-
expressions.put(":failed", AttributeValue.builder().s("failed").build());
88-
expressions.put(":deleted", AttributeValue.builder().s("deleted").build());
82+
// Get all tenants that have infrastructure running or being created
8983
List<Tenant> tenants = new ArrayList<>();
9084
try {
9185
ScanResponse response = ddb.scan(ScanRequest.builder()
9286
.tableName(TENANTS_TABLE)
93-
.filterExpression(filter)
94-
.expressionAttributeValues(expressions)
87+
.filterExpression("attribute_exists(onboarding_status) "
88+
+ "AND onboarding_status <> :failed "
89+
+ "AND onboarding_status <> :deleting "
90+
+ "AND onboarding_status <> :deleted") // Can't use NOT IN (...) in DynamoDB
91+
.expressionAttributeValues(Map.of(
92+
":failed", AttributeValue.builder().s("failed").build(),
93+
":deleting", AttributeValue.builder().s("deleting").build(),
94+
":deleted", AttributeValue.builder().s("deleted").build()
95+
))
9596
.build()
9697
);
9798
LOGGER.info("TenantServiceDAL::getProvisionedTenants returning {} provisioned tenants", response.items().size());

0 commit comments

Comments
 (0)