Related
Introduction
I am currently working on a project to achieve a bulk insertion in a Couchbase database.
For this, I chose Quarkus Reactive to get data from the client. And I used a Flux to insert all the data to database.
For each data inserted, I send a response, example of a response:
[
{
"data": {
"id": "1"
"created": "2022-02-22T00:28:34Z",
"lastName": "DUPOND",
"firstName": "Marianne",
"gender": "FEMALE",
"title": "MRS",
"addresses": [
{
"street1": "rue du Testeur",
"zipCode": "34000",
"city": "MONTPELLIER",
"country": "France",
"typeKey": "PERSONAL"
}
],
"phones": [
{
"number": "0610529856",
"typeKey": "PERSONAL"
}
],
"emails": [
{
"email": "marianne.dupond#test.com",
"typeKey": "PERSONAL"
}
],
"birthday": "1987-11-13",
"languages": [
"FR",
"EN"
],
"socialNetworks": [
{
"socialNetworkId": "marianne.dupond#twitter",
"typeKey": "PERSONAL"
}
],
"customFields": [
{
"customFieldKey": "MAIDEN_NAME",
"value": "DURAND"
}
]
},
"result": "201",
"id":"1"
},
{
"data": {
"id" : "2"
"created": "2022-02-22T00:28:34Z",
"lastName": "BOND",
"firstName": "James",
"gender": "MALE",
"title": "MR",
"addresses": [
{
"street1": "boulevard des services secrets",
"zipCode": "10000",
"city": "LONDRES",
"country": "Royaume-Uni",
"typeKey": "PERSONAL"
}
],
"phones": [
{
"number": "0600700700",
"typeKey": "PERSONAL"
}
],
"emails": [
{
"email": "james.bond#test.com",
"typeKey": "PERSONAL"
}
],
"birthday": "1950-07-07",
"languages": [
"EN"
],
"socialNetworks": [
{
"socialNetworkId": "james.bond#facebook",
"typeKey": "PERSONAL"
}
],
"customFields": [
{
"customFieldKey": "VIP",
"value": "1"
}
]
},
"result": "201",
"id": "2"
}
]
Problematic
But currently the returned response is:
[
{
"data": {
"id": "1"
"created": "2022-02-22T00:37:39Z",
"lastName": "DUPOND",
"firstName": "Marianne",
"gender": "FEMALE",
"title": "MRS",
"addresses": [
{
"street1": "rue du Testeur",
"zipCode": "34000",
"city": "MONTPELLIER",
"country": "France",
"typeKey": "PERSONAL"
}
],
"phones": [
{
"number": "0610529856",
"typeKey": "PERSONAL"
}
],
"emails": [
{
"email": "marianne.dupond#test.com",
"typeKey": "PERSONAL"
}
],
"birthday": "1987-11-13",
"languages": [
"FR",
"EN"
],
"socialNetworks": [
{
"socialNetworkId": "marianne.dupond#twitter",
"typeKey": "PERSONAL"
}
],
"customFields": [
{
"customFieldKey": "MAIDEN_NAME",
"value": "DURAND"
}
]
},
"result": "201"
},
{
"data": {
"created": "2022-02-22T00:37:39Z",
"lastName": "BOND",
"firstName": "James",
"gender": "MALE",
"title": "MR",
"addresses": [
{
"street1": "boulevard des services secrets",
"zipCode": "10000",
"city": "LONDRES",
"country": "Royaume-Uni",
"typeKey": "PERSONAL"
}
],
"phones": [
{
"number": "0600700700",
"typeKey": "PERSONAL"
}
],
"emails": [
{
"email": "james.bond#test.com",
"typeKey": "PERSONAL"
}
],
"birthday": "1950-07-07",
"languages": [
"EN"
],
"socialNetworks": [
{
"socialNetworkId": "james.bond#facebook",
"typeKey": "PERSONAL"
}
],
"customFields": [
{
"customFieldKey": "VIP",
"value": "1"
}
]
},
"result": "201"
}
]
The id field inside the data and the response field do not appear, and sometimes the id field inside the data of the first element appears, sometimes not.
Affected code
Bulk insertion(flux of single insertion) code:
public Flux<SingleResponseBulk> bulkInsertCustomerProfile(Multi<SingleResponseBulk> singleResponses) {
return Flux.from(singleResponses)
.doOnEach(signal -> {
if (signal.hasValue()) {
SingleResponseBulk singleResponseBulk = Objects.requireNonNull(signal.get());
insertCustomerProfileWithSingleResponseBulk(singleResponseBulk);
}
});
}
private void insertCustomerProfileWithSingleResponseBulk(SingleResponseBulk response) {
try {
insertCustomerProfile(response.getData()).subscribe();
response.setId(response.getData().getId());
response.setResult("201");
} catch (CouchbaseException e) {
response.setResult("400");
response.setError(e.getMessage());
}
}
Single insertion code:
public Mono<CustomerProfile> insertCustomerProfile(CustomerProfile customerProfile) {
customerProfile.setCreated(LocalDateTime.now());
return getNextId().flatMap(counterResult -> {
String id = String.valueOf(counterResult.content());
customerProfile.setId(id);
String key = getDocumentKey(id);
return collection.insert(key, customerProfile)
.flatMap(result -> {
customerProfile.setCas(result.cas());
return Mono.just(customerProfile);
})
.doOnError(CouchbaseException.class, mapCouchbaseExceptionConsumer(id));
});
}
Id generation code:
private Mono<CounterResult> getNextId() {
return collection.binary()
.increment("counter" + COLLECTION_DELIMITER + CUSTOMER_PROFILE_COLLECTION)
.doOnError(CouchbaseException.class, error -> {
String errorMessage = "An exception occurred during id generation.";
throw new RepositoryException(errorMessage, error);
});
}
Question
So I was wondering if it would be possible to solve the problem. If so, how can we do it?
I'm trying to add some tests with Rest-Assured to my application, but I can't figure out how to assert some nested values. The error message is :
Expected: (a collection containing "json")
Actual: [[json, spring, gulp, path etc...]]
Here is the code :
when().
get("/api/personsByID/{id}/{count}", 262, 2).
then().
statusCode(200).
body("personDependencies.name", hasItems("json"));
And here is the JSON file that is returned by rest controller:
[
{
"id": 346,
"verified": true,
"displayName": "eda656a2c3cb59ae840e40a28ba4ab50bfb9de0185abcb901c6af6dc59d6668f",
"emails": [
{
"email": "16a23f2e5477df0bbcad718c3abc235b2cb8a1b6648d14f58d42a7be13df2b6e"
}
],
"personDependencies": [
{
"name": "json"
},
{
"name": "spring"
},
{
"name": "gulp"
},
{
"name": "path"
},
{
"name": "junit"
},
{
"name": "activemq"
},
{
"name": "hibernate"
},
{
"name": "jstl"
},
{
"name": "phantomjs"
},
{
"name": "activiti"
},
{
"name": "commons"
},
{
"name": "h2"
},
{
"name": "joda"
},
{
"name": "log4j"
},
{
"name": "exec"
},
{
"name": "admin"
},
{
"name": "coveralls"
},
{
"name": "cxf"
},
{
"name": "cglib"
},
{
"name": "camel"
},
{
"name": "sugaronrest"
},
{
"name": "tslint"
},
{
"name": "httpclient"
},
{
"name": "guava"
},
{
"name": "inventory"
},
{
"name": "jackson"
},
{
"name": "gson"
},
{
"name": "event"
},
{
"name": "OTRS"
},
{
"name": "maven"
},
{
"name": "karma"
},
{
"name": "slf4j"
},
{
"name": "postgresql"
},
{
"name": "typescript"
},
{
"name": "jasmine"
},
{
"name": "spa"
},
{
"name": "javax.servlet"
}
],
"countries": [],
"member_of": [],
"projects": [],
"employee_type": [],
"languages": [
{
"language": "reStructuredText",
"sum": 575
},
{
"language": "JSON",
"sum": 21
},
{
"language": "JavaScript",
"sum": 4467
},
{
"language": "Java",
"sum": 7958
},
{
"language": "Python",
"sum": 2
},
{
"language": "XML",
"sum": 477
},
{
"language": "Plain Text",
"sum": 41
}
],
"distance": 0.6028837702084446
}
]
I have no idea how to make proper assertions, any help would be great. Thanks!
If I am reading your question right you need to check if a certain values are present in a list that is returned for a particular ID
The below should work for you
given().when().get().then().body("find {it.id == 346}.personDependencies.name", hasItems("json", "jackson"));
The first problem you don't need to check the presence of an item with hasItems, you should use hasItem
when().
get("/api/personsByID/{id}/{count}", 262, 2).
then().
statusCode(200).
body("personDependencies.name", hasItem("json"));
Then if you need to add more message to the assertion when the test fails you can do such way:
when().
get("/api/personsByID/{id}/{count}", 262, 2).
then().
statusCode(200).
body("personDependencies.name", describedAs("Array not containing the provided item",hasItem("json")));
In your case you can validate such a way:
when().
get("/api/personsByID/{id}/{count}", 262, 2).
then().
statusCode(200).
body("personDependencies[*].name", hasItem("json"));
I´m running the GO-CD Server and Agents as Alpine Docker containers on a linux machine
I´m adding several pipelines through the json config plugin. The Server seems to start the first Pipeline and upload all the materials. Then he triggers 2 downstream pipes who´ll fetch the materials.
The 2 Downstream pipelines are beeing scheduled and asingned to an agent but they are not starting.
I´ve stopped the stages to see if the error was still comming and they stopped too.
2018-08-29 15:34:28,029 ERROR [85#MessageListener for WorkFinder] JMSMessageListenerAdapter:77 - Exception thrown in message handling by listener com.thoughtworks.go.server.messaging.scheduling.WorkFinder#2c731a16
java.lang.NullPointerException: null
2018-08-29 15:34:36,919 ERROR [85#MessageListener for WorkFinder] JMSMessageListenerAdapter:77 - Exception thrown in message handling by listener com.thoughtworks.go.server.messaging.scheduling.WorkFinder#2c731a16
java.lang.NullPointerException: null
2018-08-29 15:34:38,040 ERROR [85#MessageListener for WorkFinder] JMSMessageListenerAdapter:77 - Exception thrown in message handling by listener com.thoughtworks.go.server.messaging.scheduling.WorkFinder#2c731a16
java.lang.NullPointerException: null
Thats how the some of the pipelines are configured in the repository
{
"format_version" : 3,
"group": "group1",
"name": "Test-Pipeline-Stage",
"label_template": "${COUNT}",
"enable_pipeline_locking" : false,
"parameters": [],
"materials": [
{
"type": "git",
"url": ""
}
],
"stages": [
{
"name": "Test",
"fetch_materials": true,
"never_cleanup_artifacts": false,
"clean_working_directory": false,
"approval" : null,
"jobs": [{
"name": "RunUnittestAndCoverage",
"run_instance_count" : "all",
"environment_variables": [],
"timeout": 1,
"tabs": [
{
"name": "coverage",
"path": "coverage/coverage.html/index.html"
}
],
"artifacts": [
{
"source":"project.tar.gz",
"destination":"project_source",
"type":"build"
},
{
"source": "test_result.xml",
"destination": "testoutput",
"type": "test"
},
{
"source": "coverage.html",
"destination": "coverage",
"type": "build"
},
{
"source": "coverage.xml",
"destination": "coverage",
"type": "build"
}
],
"tasks":[
{
"type": "exec",
"run_if": "passed",
"on_cancel": null,
"command":"tox"
},
{
"type":"exec",
"run_if": "passed",
"on_cancel": null,
"command":"/usr/bin/xmllint",
"arguments": [
"--format",
"test_resulto.xml",
"--output",
"test_result.xml"
]
},
{
"type":"exec",
"run_if": "passed",
"on_cancel": null,
"command": "/bin/ls",
"arguments":[
"-al"
]
},
{
"type":"exec",
"run_if": "passed",
"on_cancel": null,
"command": "/bin/tar",
"arguments":[
"-cvzf",
"project.tar.gz",
"/godata/pipelines/Test-Pipeline-Stage"
]
}
]
}
]
}
]
}
{
"format_version" : 3,
"group": "group1",
"name": "Docker-Deployment-Pipeline-Stage",
"label_template": "${COUNT}",
"enable_pipeline_locking" : false,
"parameters": [],
"materials": [
{
"type": "dependency",
"pipeline": "Build-Pipeline-Stage",
"stage": "BuildPythonProduct",
"name": "project_source"
},
{
"type": "dependency",
"pipeline": "Analyse-Pipeline-Stage",
"stage":"Analyse",
"name":"analyse_result"
}
],
"stages":[
{
"name": "BuildDockerImage",
"fetch_materials": true,
"never_cleanup_artifacts": false,
"clean_working_directory": false,
"approval" : null,
"jobs":[
{
"name": "BuildImage",
"run_instance_count" : "all",
"environment_variables": [],
"timeout": 1,
"tasks": [
{
"type": "fetch",
"artifact_origin": "gocd",
"run_if": "any",
"pipeline": "Build-Pipeline-Stage",
"stage": "BuildPythonProduct",
"job": "BuildAndUpLoadWheel",
"is_source_a_file": true,
"source": "docker/Dockerfile",
"destination": ""
},
{
"type": "fetch",
"artifact_origin": "gocd",
"run_if": "any",
"pipeline": "Build-Pipeline-Stage",
"stage": "BuildPythonProduct",
"job": "BuildAndUpLoadWheel",
"is_source_a_file": true,
"source": "docker/production.ini",
"destination": ""
},
{
"type":"exec",
"run_if": "passed",
"on_cancel": null,
"command":"/usr/bin/docker",
"arguments": [
"build",
"-t",
"project_creator",
"."
]
}
]
}
]
}
]
}
Below is the original response:
{
"emails": [
{
"type": "work",
"value": "bjensen#example.com"
}
],
"id": "2819c223-7f76-453a-919d-413861904646",
"phoneNumbers": [
{
"type": "work",
"value": "555-555-8377"
},
{
"type": "business",
"value": "555-555-8377"
}
],
"schemas": [
"urn:scim:schemas:core:1.0"
],
"userName": "bjensen"
}
And in the above response I would pass excludedAttributes=phoneNumbers.type and the response should be like below:
{
"emails": [
{
"type": "work",
"value": "bjensen#example.com"
}
],
"id": "2819c223-7f76-453a-919d-413861904646",
"phoneNumbers": [
{
"value": "555-555-8377"
},
{
"value": "555-555-8377"
}
],
"schemas": [
"urn:scim:schemas:core:1.0"
],
"userName": "bjensen"
}
In our template, we setup java, build our application and try to run it.
Everything works as expected, but running the app just won't work. I seems like AWS is waiting for the command to finish but never gets a response (because our Spring Boot Rest Backend would need to terminate for the command to return). I know we did some things in the template that we shouldn't, but how can we run out app from that template, so that AWS accepts the status as healthy (and therefore doesn't rollback)? Focus on the commands in the init section. That's where stuff is happening.
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AWS playground",
"Parameters": {
"KeyName": {
"Description": "Key Pair name",
"Type": "AWS::EC2::KeyPair::KeyName",
"Default": "xyz"
}
},
"Mappings": {
"EC2RegionMap": {
"ap-northeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-cbf90ecb"},
"ap-southeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-68d8e93a"},
"ap-southeast-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-fd9cecc7"},
"eu-central-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a8221fb5"},
"eu-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a10897d6"},
"sa-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-b52890a8"},
"us-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-1ecae776"},
"us-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-d114f295"},
"us-west-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-e7527ed7"}
}
},
"Resources": {
"VPC": {
"Type": "AWS::EC2::VPC",
"Properties": {
"CidrBlock": "172.31.0.0/16",
"EnableDnsHostnames": "true"
}
},
"InternetGateway": {
"Type": "AWS::EC2::InternetGateway",
"Properties": {}
},
"VPCGatewayAttachment": {
"Type": "AWS::EC2::VPCGatewayAttachment",
"Properties": {
"VpcId": {"Ref": "VPC"},
"InternetGatewayId": {"Ref": "InternetGateway"}
}
},
"SubnetA": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},
"CidrBlock": "172.31.38.0/24",
"VpcId": {"Ref": "VPC"}
}
},
"SubnetB": {
"Type": "AWS::EC2::Subnet",
"Properties": {
"AvailabilityZone": {"Fn::Select": ["1", {"Fn::GetAZs": ""}]},
"CidrBlock": "172.31.37.0/24",
"VpcId": {"Ref": "VPC"}
}
},
"RouteTable": {
"Type": "AWS::EC2::RouteTable",
"Properties": {
"VpcId": {"Ref": "VPC"}
}
},
"RouteTableAssociationA": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": {"Ref": "SubnetA"},
"RouteTableId": {"Ref": "RouteTable"}
}
},
"RouteTableAssociationB": {
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"Properties": {
"SubnetId": {"Ref": "SubnetB"},
"RouteTableId": {"Ref": "RouteTable"}
}
},
"RoutePublicNATToInternet": {
"Type": "AWS::EC2::Route",
"Properties": {
"RouteTableId": {"Ref": "RouteTable"},
"DestinationCidrBlock": "0.0.0.0/0",
"GatewayId": {"Ref": "InternetGateway"}
},
"DependsOn": "VPCGatewayAttachment"
},
"NetworkAcl": {
"Type": "AWS::EC2::NetworkAcl",
"Properties": {
"VpcId": {"Ref": "VPC"}
}
},
"SubnetNetworkAclAssociationA": {
"Type": "AWS::EC2::SubnetNetworkAclAssociation",
"Properties": {
"SubnetId": {"Ref": "SubnetA"},
"NetworkAclId": {"Ref": "NetworkAcl"}
}
},
"SubnetNetworkAclAssociationB": {
"Type": "AWS::EC2::SubnetNetworkAclAssociation",
"Properties": {
"SubnetId": {"Ref": "SubnetB"},
"NetworkAclId": {"Ref": "NetworkAcl"}
}
},
"NetworkAclEntryIngress": {
"Type": "AWS::EC2::NetworkAclEntry",
"Properties": {
"NetworkAclId": {"Ref": "NetworkAcl"},
"RuleNumber": "100",
"Protocol": "-1",
"RuleAction": "allow",
"Egress": "false",
"CidrBlock": "0.0.0.0/0"
}
},
"NetworkAclEntryEgress": {
"Type": "AWS::EC2::NetworkAclEntry",
"Properties": {
"NetworkAclId": {"Ref": "NetworkAcl"},
"RuleNumber": "100",
"Protocol": "-1",
"RuleAction": "allow",
"Egress": "true",
"CidrBlock": "0.0.0.0/0"
}
},
"LoadBalancer": {
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties": {
"Subnets": [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}],
"LoadBalancerName": "school-elb",
"Listeners": [{
"InstancePort": "80",
"InstanceProtocol": "HTTP",
"LoadBalancerPort": "80",
"Protocol": "HTTP"
}],
"HealthCheck": {
"HealthyThreshold": "2",
"Interval": "5",
"Target": "TCP:80",
"Timeout": "3",
"UnhealthyThreshold": "2"
},
"SecurityGroups": [{"Ref": "LoadBalancerSecurityGroup"}],
"Scheme": "internet-facing"
},
"DependsOn": "VPCGatewayAttachment"
},
"LoadBalancerSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "school-elb-sg",
"VpcId": {"Ref": "VPC"},
"SecurityGroupIngress": [{
"CidrIp": "0.0.0.0/0",
"FromPort": "80",
"IpProtocol": "tcp",
"ToPort": "80"
}]
}
},
"WebServerSecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "school-sg",
"VpcId": {"Ref": "VPC"},
"SecurityGroupIngress": [{
"CidrIp": "0.0.0.0/0",
"FromPort": "22",
"IpProtocol": "tcp",
"ToPort": "22"
}, {
"FromPort": "80",
"ToPort": "80",
"IpProtocol": "tcp",
"SourceSecurityGroupId": {"Ref": "LoadBalancerSecurityGroup"}
}]
}
},
"LaunchConfiguration": {
"Type": "AWS::AutoScaling::LaunchConfiguration",
"Metadata": {
"AWS::CloudFormation::Init": {
"config": {
"packages": {
"yum": {
"java-1.8.0-openjdk-devel": []
}
},
"sources": {
"/opt": "https://services.gradle.org/distributions/gradle-3.4.1-bin.zip",
"/home/ec2-user": "https://github.com/yandypiedra/AWS_Cloud_Formation/archive/master.zip"
},
"files": {
"/tmp/depend_config": {
"content": {
"Fn::Join": [
"",
[
"#!/bin/bash -ex\n",
"chmod -R 755 gradle-3.4.1/\n",
"echo \"PATH=$PATH:/opt/gradle-3.4.1/bin\" >> /etc/environment\n",
"yum install -y java-1.8.0\n"
]
]
},
"mode": "000500",
"owner": "root",
"group": "root"
},
"/tmp/app_config": {
"content": {
"Fn::Join": [
"",
[
"#!/bin/bash -ex\n",
"chmod -R 777 AWS_Cloud_Formation-master/\n",
"/opt/gradle-3.4.1/bin/gradle build -p /home/ec2-user/AWS_Cloud_Formation-master/src/Hi/\n"
]
]
},
"mode": "000500",
"owner": "root",
"group": "root"
},
"/tmp/launch_server": {
"content": {
"Fn::Join": [
"",
[
"#!/bin/bash -ex\n",
"chmod -R 777 AWS_Cloud_Formation-master/\n",
"java -jar AWS_Cloud_Formation-master/src/Hi/build/libs/hi-1.0-SNAPSHOT.jar\n"
]
]
},
"mode": "000500",
"owner": "root",
"group": "root"
}
},
"commands": {
"01_config": {
"command": "/tmp/depend_config",
"cwd": "/opt"
},
"02_config": {
"command": "yum remove -y java-1.7.0-openjdk"
},
"03_config": {
"command": "/tmp/app_config",
"cwd": "/home/ec2-user"
},
"04_config": {
"command": "/tmp/launch_server",
"cwd": "/home/ec2-user"
}
}
}
}
},
"Properties": {
"EbsOptimized": false,
"ImageId": {"Fn::FindInMap": ["EC2RegionMap", {"Ref": "AWS::Region"}, "AmazonLinuxAMIHVMEBSBacked64bit"]},
"InstanceType": "t2.micro",
"SecurityGroups": [{"Ref": "WebServerSecurityGroup"}],
"KeyName": {"Ref": "KeyName"},
"AssociatePublicIpAddress": true,
"UserData": {"Fn::Base64": {"Fn::Join": ["", [
"#!/bin/bash -ex\n",
"yum update -y aws-cfn-bootstrap\n",
"/opt/aws/bin/cfn-init -v --stack ", {"Ref": "AWS::StackName"}, " --resource LaunchConfiguration --region ", {"Ref": "AWS::Region"}, "\n",
"/opt/aws/bin/cfn-signal -e $? --stack ", {"Ref": "AWS::StackName"}, " --resource AutoScalingGroup --region ", {"Ref": "AWS::Region"}, "\n"
]]}}
}
},
"AutoScalingGroup": {
"Type": "AWS::AutoScaling::AutoScalingGroup",
"Properties": {
"LoadBalancerNames": [{"Ref": "LoadBalancer"}],
"LaunchConfigurationName": {"Ref": "LaunchConfiguration"},
"MinSize": "1",
"MaxSize": "1",
"DesiredCapacity": "1",
"VPCZoneIdentifier": [{"Ref": "SubnetA"}, {"Ref": "SubnetB"}]
},
"CreationPolicy": {
"ResourceSignal": {
"Timeout": "PT15M"
}
},
"DependsOn": "VPCGatewayAttachment"
}
}
}
Try running it as a service/deamon? Or maybe use a nohup