Demonstrate updating user's status through GCP Background Function
- JDK 11 or later
- Project Lombok
- Spring Cloud Function GCP Adapter
- Spring Data MongoDB
- MongoDB TestContainers
- LocalServerTestSupport.java from Spring Cloud Function samples
Full dependencies can be found in pom.xml
We will start by implementing test which will verify that User's status will be updated. Our test will be based on the following scenario:
Given user status is ACTIVE
When a message is published with user status DORMANT
Then user status in database should be DORMANT
This is demonstrated in the following implementation:
class UpdateUserStatusApplicationTests {
@Test
@DisplayName("User status will be updated based on provided value in message")
void contextLoads() throws IOException, InterruptedException {
var restTemplate = new TestRestTemplate();
var message = messageWithNewUserStatus();
try(var process = startServer(UpdateUserStatusApplication.class, MONGO_DB_CONTAINER)) {
restTemplate.postForObject("http://localhost:8080/", message, String.class);
}
var updatedUser = findById(user.getId());
assertThat(updatedUser.getStatus()).isEqualTo(DORMANT);
}
private User findById(ObjectId id) {
return template.findById(id, User.class);
}
private PubSubMessage messageWithNewUserStatus() {
var message = new PubSubMessage();
message.setAttributes(Map.of(
"id", user.getId().toString(),
"status", DORMANT.name()
));
return message;
}
}
Full implementation can be found in UpdateUserStatusApplicationTests.
UserRepository will be responsible to update User based on provided UserStatus
@Repository
@AllArgsConstructor
public class UserRepository {
private final MongoTemplate template;
public void updateStatusById(ObjectId id, UserStatus newStatus) {
template.updateFirst(
query(where("_id").is(id)),
update("status", newStatus),
User.class
);
}
}
Next, we will implement a Background Function that will be triggered through
PubSubMessage. PubSubMessage
is a class
that contains the structure of
GCP Pubsub Message structure.
@Component
@AllArgsConstructor
public class UpdateUserStatusFunction implements Consumer<PubSubMessage> {
private final UserRepository repository;
@Override
public void accept(PubSubMessage message) {
var attributes = message.getAttributes();
var id = new ObjectId(attributes.get("id"));
var newStatus = UserStatus.valueOf(attributes.get("status"));
repository.updateStatusById(id, newStatus);
}
}
Finally, we will need to specify our configuration main class. This is defined in MANIFEST.MF
Main-Class: scratches.boot.cloud.user.UpdateUserStatusApplication
Once all are implemented, we will verify that our implementation works by executing UpdateUserStatusApplicationTests.contextLoads
. If all
implementation is correct, our verification that asserts UserStatus
is now DORMANT
will pass.
class UpdateUserStatusApplicationTests {
@Test
@DisplayName("User status will be updated based on provided value in message")
void contextLoads() throws IOException, InterruptedException {
var updatedUser = findById(user.getId());
assertThat(updatedUser.getStatus()).isEqualTo(DORMANT);
}
}
We can also run the function locally through the following command:
mvn function:run
You can find more information at Spring Cloud Function - Google Cloud Functions