Fork me on GitHub

Google Function Tutorial

This tutorial demonstrates running within Google Functions.

Tutorial Source

Google Functions

Google Functions is supported by OfficeFloor through the following plugin:

		<dependency>
			<groupId>net.officefloor.server</groupId>
			<artifactId>officeserver_googlefunction</artifactId>
		</dependency>

The only additional configuration is Google Function requiring the application be shaded as follows:

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<configuration>
					<transformers>
						<transformer
							implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
					</transformers>
					<filters>
						<filter>
							<!-- Exclude signing -->
							<artifact>*</artifact>
							<excludes>
								<exclude>META-INF/*.SF</exclude>
								<exclude>META-INF/*.DSA</exclude>
								<exclude>META-INF/*.RSA</exclude>
							</excludes>
						</filter>
					</filters>
				</configuration>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

Running Locally

Running the Google Function application locally typically requires running Firestore and then starting local emulation of Google Functions. To ease running and testing the application, the following plugin is available:

					<plugin>
						<groupId>net.officefloor.maven</groupId>
						<artifactId>officefloor-googlefunction-maven-plugin</artifactId>
						<configuration>
							<httpPort>8381</httpPort>
							<firestorePort>8383</firestorePort>
						</configuration>
						<executions>
							<execution>
								<id>start</id>
								<phase>pre-integration-test</phase>
								<goals>
									<goal>start</goal>
								</goals>
							</execution>
							<execution>
								<id>stop</id>
								<phase>post-integration-test</phase>
								<goals>
									<goal>stop</goal>
								</goals>
							</execution>
						</executions>
					</plugin>

					<!-- Run integration tests against locally started Google Function -->
					<plugin>
						<groupId>org.apache.maven.plugins</groupId>
						<artifactId>maven-failsafe-plugin</artifactId>
						<executions>
							<execution>
								<goals>
									<goal>integration-test</goal>
									<goal>verify</goal>
								</goals>
							</execution>
						</executions>
					</plugin>

The application may then be manually started with the following:


    mvn officefloor-googlefunction:run

Testing

The functionality can be tested just like any other Web on OfficeFloor (WoOF) application:

	public static final @Order(1) @RegisterExtension FirestoreExtension firestore = new FirestoreExtension();

	public static final @Order(2) @RegisterExtension MockWoofServerExtension server = new MockWoofServerExtension();

	@Test
	public void createPost() throws Exception {

		// Create the entity
		MockWoofResponse response = server
				.send(MockWoofServer.mockJsonRequest(HttpMethod.POST, "/posts", new Post("TEST")));
		PostEntity entity = response.getJson(200, PostEntity.class);

		// Ensure in store
		PostEntity post = firestore.getFirestore().collection(PostEntity.class.getSimpleName()).document(entity.getId())
				.get().get().toObject(PostEntity.class);
		assertNotNull(post, "Should find entity in Firestore " + entity.getId());
		assertEquals("TEST", post.getMessage(), "Incorrent entity");
	}

To test within the Google Function emulator, use integration testing. The officefloor-googlefunction-maven-plugin above sets up the application running within a Google Function emulator. It also sets up a local Firestore. This enables the following integration testing:

	public static final @RegisterExtension HttpClientExtension serverClient = new HttpClientExtension(false, 8381)
			.timeout(30_000);

	public static final @Order(1) @RegisterExtension FirestoreConnectExtension firestore = new FirestoreConnectExtension(
			new Configuration().port(8383));

	private static final ObjectMapper mapper = new ObjectMapper();

	@Test
	public void createPost() throws Exception {

		// Create the entity
		HttpPost request = new HttpPost(serverClient.url("/posts"));
		request.setHeader("Content-Type", "application/json");
		request.setEntity(new StringEntity(mapper.writeValueAsString(new Post("TEST"))));
		HttpResponse response = serverClient.execute(request);
		String responseBody = EntityUtils.toString(response.getEntity());
		assertEquals(200, response.getStatusLine().getStatusCode(), "Should be successful: " + responseBody);
		PostEntity entity = mapper.readValue(responseBody, PostEntity.class);

		// Ensure in store
		PostEntity post = firestore.getFirestore().collection(PostEntity.class.getSimpleName()).document(entity.getId())
				.get().get().toObject(PostEntity.class);
		assertNotNull(post, "Should find entity in Firestore " + entity.getId());
		assertEquals("TEST", post.getMessage(), "Incorrent entity");
	}

Note that a different Firestore extension is used for each type of testing:

Next

Return to the tutorials index.