diff --git a/powertools-common/src/test/java/software/amazon/lambda/powertools/common/stubs/TestLambdaContext.java b/powertools-common/src/test/java/software/amazon/lambda/powertools/common/stubs/TestLambdaContext.java index 6b66b66b7..f54db723b 100644 --- a/powertools-common/src/test/java/software/amazon/lambda/powertools/common/stubs/TestLambdaContext.java +++ b/powertools-common/src/test/java/software/amazon/lambda/powertools/common/stubs/TestLambdaContext.java @@ -74,4 +74,9 @@ public int getMemoryLimitInMB() { public LambdaLogger getLogger() { return null; } + + @Override + public String getTenantId() { + return "test-tenant"; + } } diff --git a/powertools-logging/powertools-logging-log4j/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/PowertoolsResolver.java b/powertools-logging/powertools-logging-log4j/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/PowertoolsResolver.java index cef5b86ee..a3283e38a 100644 --- a/powertools-logging/powertools-logging-log4j/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/PowertoolsResolver.java +++ b/powertools-logging/powertools-logging-log4j/src/main/java/org/apache/logging/log4j/layout/template/json/resolver/PowertoolsResolver.java @@ -25,6 +25,7 @@ import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.FUNCTION_VERSION; import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.SAMPLING_RATE; import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.SERVICE; +import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.TENANT_ID; import java.io.IOException; import java.util.Collections; @@ -186,6 +187,23 @@ public void resolve(LogEvent logEvent, JsonWriter jsonWriter) { } }; + private static final EventResolver TENANT_ID_RESOLVER = new EventResolver() { + @Override + public boolean isResolvable(LogEvent logEvent) { + final String tenantId = + logEvent.getContextData().getValue(PowertoolsLoggedFields.TENANT_ID.getName()); + return null != tenantId && !tenantId.isEmpty(); + } + + @Override + public void resolve(LogEvent logEvent, JsonWriter jsonWriter) { + final String tenantId = + logEvent.getContextData().getValue(PowertoolsLoggedFields.TENANT_ID.getName()); + jsonWriter.writeString(tenantId); + } + }; + + @SuppressWarnings("java:S106") private static final EventResolver NON_POWERTOOLS_FIELD_RESOLVER = (LogEvent logEvent, JsonWriter jsonWriter) -> { @@ -233,6 +251,7 @@ public void resolve(LogEvent logEvent, JsonWriter jsonWriter) { { FUNCTION_TRACE_ID.getName(), XRAY_TRACE_RESOLVER }, { CORRELATION_ID.getName(), CORRELATION_ID_RESOLVER }, { SAMPLING_RATE.getName(), SAMPLING_RATE_RESOLVER }, + { TENANT_ID.getName(), TENANT_ID_RESOLVER }, { "region", REGION_RESOLVER }, { "account_id", ACCOUNT_ID_RESOLVER } }).collect(Collectors.toMap(data -> (String) data[0], data -> (EventResolver) data[1]))); diff --git a/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaEcsLayout.json b/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaEcsLayout.json index 58b30f60e..24dbaa0ba 100644 --- a/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaEcsLayout.json +++ b/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaEcsLayout.json @@ -87,7 +87,11 @@ "$resolver": "powertools", "field": "correlation_id" }, + "tenant.id": { + "$resolver": "powertools", + "field": "tenant_id" + }, "": { "$resolver": "powertools" } -} +} \ No newline at end of file diff --git a/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaJsonLayout.json b/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaJsonLayout.json index 793006502..1e9b5f4db 100644 --- a/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaJsonLayout.json +++ b/powertools-logging/powertools-logging-log4j/src/main/resources/LambdaJsonLayout.json @@ -69,7 +69,11 @@ "$resolver": "powertools", "field": "correlation_id" }, + "tenant_id": { + "$resolver": "powertools", + "field": "tenant_id" + }, "": { "$resolver": "powertools" } -} +} \ No newline at end of file diff --git a/powertools-logging/powertools-logging-log4j/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/PowerToolsResolverFactoryTest.java b/powertools-logging/powertools-logging-log4j/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/PowerToolsResolverFactoryTest.java index 46b5b65d4..7ff7abaaa 100644 --- a/powertools-logging/powertools-logging-log4j/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/PowerToolsResolverFactoryTest.java +++ b/powertools-logging/powertools-logging-log4j/src/test/java/org/apache/logging/log4j/layout/template/json/resolver/PowerToolsResolverFactoryTest.java @@ -79,7 +79,9 @@ void shouldLogInJsonFormat() { File logFile = new File("target/logfile.json"); assertThat(contentOf(logFile)).contains( "{\"level\":\"DEBUG\",\"message\":\"Test debug event\",\"cold_start\":true,\"function_arn\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"function_memory_size\":128,\"function_name\":\"test-function\",\"function_request_id\":\"test-request-id\",\"function_version\":\"1\",\"service\":\"testLog4j\",\"timestamp\":") - .contains("\"xray_trace_id\":\"1-63441c4a-abcdef012345678912345678\",\"myKey\":\"myValue\"}\n"); + .contains("\"xray_trace_id\":\"1-63441c4a-abcdef012345678912345678\"") + .contains("\"tenant_id\":\"test-tenant\"") + .contains("\"myKey\":\"myValue\""); } @Test @@ -89,7 +91,9 @@ void shouldLogInEcsFormat() { File logFile = new File("target/ecslogfile.json"); assertThat(contentOf(logFile)).contains( - "\"ecs.version\":\"1.2.0\",\"log.level\":\"DEBUG\",\"message\":\"Test debug event\",\"service.name\":\"testLog4j\",\"service.version\":\"1\",\"log.logger\":\"software.amazon.lambda.powertools.logging.internal.handler.PowertoolsLogEnabled\",\"process.thread.name\":\"main\",\"cloud.provider\":\"aws\",\"cloud.service.name\":\"lambda\",\"cloud.region\":\"eu-central-1\",\"cloud.account.id\":\"123456789012\",\"faas.id\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"faas.name\":\"test-function\",\"faas.version\":\"1\",\"faas.memory\":128,\"faas.execution\":\"test-request-id\",\"faas.coldstart\":true,\"trace.id\":\"1-63441c4a-abcdef012345678912345678\",\"myKey\":\"myValue\"}\n"); + "\"ecs.version\":\"1.2.0\",\"log.level\":\"DEBUG\",\"message\":\"Test debug event\",\"service.name\":\"testLog4j\",\"service.version\":\"1\",\"log.logger\":\"software.amazon.lambda.powertools.logging.internal.handler.PowertoolsLogEnabled\",\"process.thread.name\":\"main\",\"cloud.provider\":\"aws\",\"cloud.service.name\":\"lambda\",\"cloud.region\":\"eu-central-1\",\"cloud.account.id\":\"123456789012\",\"faas.id\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"faas.name\":\"test-function\",\"faas.version\":\"1\",\"faas.memory\":128,\"faas.execution\":\"test-request-id\",\"faas.coldstart\":true,\"trace.id\":\"1-63441c4a-abcdef012345678912345678\"") + .contains("\"tenant.id\":\"test-tenant\"") + .contains("\"myKey\":\"myValue\""); } } diff --git a/powertools-logging/powertools-logging-logback/src/main/java/software/amazon/lambda/powertools/logging/logback/LambdaEcsEncoder.java b/powertools-logging/powertools-logging-logback/src/main/java/software/amazon/lambda/powertools/logging/logback/LambdaEcsEncoder.java index b934f378d..629224011 100644 --- a/powertools-logging/powertools-logging-logback/src/main/java/software/amazon/lambda/powertools/logging/logback/LambdaEcsEncoder.java +++ b/powertools-logging/powertools-logging-logback/src/main/java/software/amazon/lambda/powertools/logging/logback/LambdaEcsEncoder.java @@ -24,6 +24,7 @@ import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.FUNCTION_TRACE_ID; import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.FUNCTION_VERSION; import static software.amazon.lambda.powertools.logging.logback.JsonUtils.*; +import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.TENANT_ID; import ch.qos.logback.classic.pattern.ThrowableHandlingConverter; import ch.qos.logback.classic.pattern.ThrowableProxyConverter; @@ -72,6 +73,7 @@ public class LambdaEcsEncoder extends EncoderBase { protected static final String FUNCTION_MEMORY_ATTR_NAME = "faas.memory"; protected static final String FUNCTION_TRACE_ID_ATTR_NAME = "trace.id"; protected static final String CORRELATION_ID_ATTR_NAME = "correlation.id"; + protected static final String TENANT_ID_ATTR_NAME = "tenant.id"; protected static final String ECS_VERSION = "1.2.0"; protected static final String CLOUD_PROVIDER = "aws"; @@ -169,6 +171,12 @@ private void serializeFunctionInfo(JsonSerializer serializer, String arn, Map sortedMap, JsonSerializ if (includePowertoolsInfo) { for (Map.Entry entry : sortedMap.entrySet()) { if (PowertoolsLoggedFields.stringValues().contains(entry.getKey()) - && !(entry.getKey().equals(PowertoolsLoggedFields.SAMPLING_RATE.getName()) && entry.getValue().equals("0.0"))) { + && !(entry.getKey().equals(PowertoolsLoggedFields.SAMPLING_RATE.getName()) && "0.0".equals(entry.getValue())) + && !(entry.getKey().equals(PowertoolsLoggedFields.TENANT_ID.getName()) + && (entry.getValue() == null || entry.getValue().isEmpty()))) { serializeMDCEntry(entry, serializer); } } @@ -236,6 +238,7 @@ public void setIncludeThreadInfo(boolean includeThreadInfo) { *
  • xray_trace_id
  • *
  • sampling_rate
  • *
  • service
  • + *
  • tenant_id
  • * *
    * We strongly recommend to keep these information. diff --git a/powertools-logging/powertools-logging-logback/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaEcsEncoderTest.java b/powertools-logging/powertools-logging-logback/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaEcsEncoderTest.java index 2d5cb0a00..12887d608 100644 --- a/powertools-logging/powertools-logging-logback/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaEcsEncoderTest.java +++ b/powertools-logging/powertools-logging-logback/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaEcsEncoderTest.java @@ -88,7 +88,7 @@ void shouldLogInEcsFormat() { File logFile = new File("target/ecslogfile.json"); assertThat(contentOf(logFile)).contains( - "\"ecs.version\":\"1.2.0\",\"log.level\":\"DEBUG\",\"message\":\"Test debug event\",\"service.name\":\"testLogback\",\"service.version\":\"1\",\"log.logger\":\"software.amazon.lambda.powertools.logging.internal.handler.PowertoolsLogEnabled\",\"process.thread.name\":\"main\",\"cloud.provider\":\"aws\",\"cloud.service.name\":\"lambda\",\"cloud.region\":\"us-east-1\",\"cloud.account.id\":\"123456789012\",\"faas.id\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"faas.name\":\"test-function\",\"faas.version\":\"1\",\"faas.memory\":\"128\",\"faas.execution\":\"test-request-id\",\"faas.coldstart\":\"true\",\"trace.id\":\"1-63441c4a-abcdef012345678912345678\",\"myKey\":\"myValue\"}\n"); + "\"ecs.version\":\"1.2.0\",\"log.level\":\"DEBUG\",\"message\":\"Test debug event\",\"service.name\":\"testLogback\",\"service.version\":\"1\",\"log.logger\":\"software.amazon.lambda.powertools.logging.internal.handler.PowertoolsLogEnabled\",\"process.thread.name\":\"main\",\"cloud.provider\":\"aws\",\"cloud.service.name\":\"lambda\",\"cloud.region\":\"us-east-1\",\"cloud.account.id\":\"123456789012\",\"faas.id\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"faas.name\":\"test-function\",\"faas.version\":\"1\",\"faas.memory\":\"128\",\"faas.execution\":\"test-request-id\",\"faas.coldstart\":\"true\",\"trace.id\":\"1-63441c4a-abcdef012345678912345678\",\"tenant.id\":\"test-tenant\",\"myKey\":\"myValue\"}\n"); } private final LoggingEvent loggingEvent = new LoggingEvent("fqcn", logger, Level.INFO, "message", null, null); @@ -165,8 +165,11 @@ void shouldLogException() { result = new String(encoded, StandardCharsets.UTF_8); // THEN (stack is logged with root cause first) - assertThat(result).contains( - "\"message\":\"Error\",\"error.message\":\"Unexpected value\",\"error.type\":\"java.lang.IllegalStateException\",\"error.stack_trace\":\"java.lang.IllegalStateException: Unexpected value\\n"); + assertThat(result) + .contains("\"message\":\"Error\",\"error.message\":\"Unexpected value\",\"error.type\":\"java.lang.IllegalStateException\"") + .containsAnyOf( + "\"error.stack_trace\":\"java.lang.IllegalStateException: Unexpected value\\n", + "\"error.stack_trace\":\"java.lang.IllegalStateException: Unexpected value\\r\\n"); } private void setMDC() { diff --git a/powertools-logging/powertools-logging-logback/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaJsonEncoderTest.java b/powertools-logging/powertools-logging-logback/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaJsonEncoderTest.java index ca256ad5d..75ef79369 100644 --- a/powertools-logging/powertools-logging-logback/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaJsonEncoderTest.java +++ b/powertools-logging/powertools-logging-logback/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaJsonEncoderTest.java @@ -111,8 +111,8 @@ void shouldLogInJsonFormat() { // THEN File logFile = new File("target/logfile.json"); assertThat(contentOf(logFile)).contains( - "{\"level\":\"DEBUG\",\"message\":\"Test debug event\",\"cold_start\":true,\"function_arn\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"function_memory_size\":128,\"function_name\":\"test-function\",\"function_request_id\":\"test-request-id\",\"function_version\":1,\"service\":\"testLogback\",\"xray_trace_id\":\"1-63441c4a-abcdef012345678912345678\",\"myKey\":\"myValue\",\"timestamp\":"); - } + "{\"level\":\"DEBUG\",\"message\":\"Test debug event\",\"cold_start\":true,\"function_arn\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"function_memory_size\":128,\"function_name\":\"test-function\",\"function_request_id\":\"test-request-id\",\"function_version\":1,\"service\":\"testLogback\",\"tenant_id\":\"test-tenant\",\"xray_trace_id\":\"1-63441c4a-abcdef012345678912345678\",\"myKey\":\"myValue\",\"timestamp\":\""); + } @Test void shouldLogArgumentsAsJsonWhenUsingRawJson() { @@ -196,6 +196,7 @@ void shouldNotLogPowertoolsInfo() { MDC.put(PowertoolsLoggedFields.FUNCTION_COLD_START.getName(), "false"); MDC.put(PowertoolsLoggedFields.SAMPLING_RATE.getName(), "0.2"); MDC.put(PowertoolsLoggedFields.SERVICE.getName(), "Service"); + MDC.put(PowertoolsLoggedFields.TENANT_ID.getName(), "test-tenant"); // WHEN byte[] encoded = encoder.encode(loggingEvent); @@ -203,7 +204,8 @@ void shouldNotLogPowertoolsInfo() { // THEN assertThat(result).contains( - "{\"level\":\"INFO\",\"message\":\"message\",\"cold_start\":false,\"function_arn\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"function_memory_size\":128,\"function_name\":\"test-function\",\"function_request_id\":\"test-request-id\",\"function_version\":1,\"sampling_rate\":0.2,\"service\":\"Service\",\"timestamp\":"); + "{\"level\":\"INFO\",\"message\":\"message\",\"cold_start\":false,\"function_arn\":\"arn:aws:lambda:us-east-1:123456789012:function:test\",\"function_memory_size\":128,\"function_name\":\"test-function\",\"function_request_id\":\"test-request-id\",\"function_version\":1,\"sampling_rate\":0.2,\"service\":\"Service\",\"tenant_id\":\"test-tenant\",\"timestamp\":\"" + ); // WHEN (powertoolsInfo = false) encoder.setIncludePowertoolsInfo(false); @@ -212,7 +214,7 @@ void shouldNotLogPowertoolsInfo() { // THEN (no powertools info in logs) assertThat(result).doesNotContain("cold_start", "function_arn", "function_memory_size", "function_name", - "function_request_id", "function_version", "sampling_rate", "service"); + "function_request_id", "function_version", "sampling_rate", "service", "tenant_id"); } @Test @@ -441,7 +443,9 @@ void shouldLogException() { // THEN (stack is logged with root cause first) assertThat(result).contains("\"message\":\"Unexpected value\"") .contains("\"name\":\"java.lang.IllegalStateException\"") - .contains("\"stack\":\"java.lang.IllegalStateException: Unexpected value\\n"); + .containsAnyOf( + "\"stack\":\"java.lang.IllegalStateException: Unexpected value\\n", + "\"stack\":\"java.lang.IllegalStateException: Unexpected value\\r\\n"); } @Test @@ -481,4 +485,33 @@ void shouldLogKeyValuePairs() { ; } + @Test + void shouldNotLogTenantIdWhenNull() { + // GIVEN + LambdaJsonEncoder encoder = new LambdaJsonEncoder(); + MDC.put(PowertoolsLoggedFields.TENANT_ID.getName(), null); + + // WHEN + byte[] encoded = encoder.encode(loggingEvent); + String result = new String(encoded, StandardCharsets.UTF_8); + + // THEN + assertThat(result).doesNotContain("tenant_id"); + } + + @Test + void shouldNotLogTenantIdWhenEmpty() { + // GIVEN + LambdaJsonEncoder encoder = new LambdaJsonEncoder(); + MDC.put(PowertoolsLoggedFields.TENANT_ID.getName(), ""); + + // WHEN + byte[] encoded = encoder.encode(loggingEvent); + String result = new String(encoded, StandardCharsets.UTF_8); + + // THEN + assertThat(result).doesNotContain("tenant_id"); + } + + } diff --git a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/PowertoolsLoggedFields.java b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/PowertoolsLoggedFields.java index 2545396d2..ad47608a8 100644 --- a/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/PowertoolsLoggedFields.java +++ b/powertools-logging/src/main/java/software/amazon/lambda/powertools/logging/internal/PowertoolsLoggedFields.java @@ -35,7 +35,8 @@ public enum PowertoolsLoggedFields { FUNCTION_TRACE_ID("xray_trace_id"), SAMPLING_RATE("sampling_rate"), CORRELATION_ID("correlation_id"), - SERVICE("service"); + SERVICE("service"), + TENANT_ID("tenant_id"); private final String name; @@ -55,6 +56,10 @@ public static Map setValuesFromLambdaContext(Context context) { hashMap.put(FUNCTION_ARN.name, context.getInvokedFunctionArn()); hashMap.put(FUNCTION_MEMORY_SIZE.name, String.valueOf(context.getMemoryLimitInMB())); hashMap.put(FUNCTION_REQUEST_ID.name, String.valueOf(context.getAwsRequestId())); + String tenantId = context.getTenantId(); + if (tenantId != null && !tenantId.isEmpty()) { + hashMap.put(TENANT_ID.name, tenantId); + } return hashMap; } diff --git a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/KeyBufferTest.java b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/KeyBufferTest.java index fac85e230..9656c58d2 100644 --- a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/KeyBufferTest.java +++ b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/KeyBufferTest.java @@ -351,9 +351,9 @@ void shouldUseDefaultWarningLoggerWhenNotProvided() { defaultBuffer.removeAll("key1"); // Assert System.err received the warning - assertThat(errCapture) - .hasToString( - "WARN [KeyBuffer] - Some logs are not displayed because they were evicted from the buffer. Increase buffer size to store more logs in the buffer.\n"); + assertThat(errCapture.toString()) + .contains( + "WARN [KeyBuffer] - Some logs are not displayed because they were evicted from the buffer. Increase buffer size to store more logs in the buffer."); } finally { System.setErr(originalErr); } diff --git a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java index ca47f9097..158bffb94 100644 --- a/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java +++ b/powertools-logging/src/test/java/software/amazon/lambda/powertools/logging/internal/LambdaLoggingAspectTest.java @@ -26,6 +26,7 @@ import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.FUNCTION_TRACE_ID; import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.FUNCTION_VERSION; import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.SERVICE; +import static software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields.TENANT_ID; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -88,7 +89,7 @@ class LambdaLoggingAspectTest { - private static final int EXPECTED_CONTEXT_SIZE = 8; + private static final int EXPECTED_CONTEXT_SIZE = 9; private RequestStreamHandler requestStreamHandler; private RequestHandler requestHandler; @@ -148,6 +149,7 @@ void shouldSetLambdaContextWhenEnabled() { .containsEntry(FUNCTION_VERSION.getName(), "1") .containsEntry(FUNCTION_NAME.getName(), "test-function") .containsEntry(FUNCTION_REQUEST_ID.getName(), "test-request-id") + .containsEntry(TENANT_ID.getName(), "test-tenant") .containsKey(FUNCTION_COLD_START.getName()) .containsKey(SERVICE.getName()); } @@ -166,6 +168,7 @@ void shouldSetLambdaContextForStreamHandlerWhenEnabled() throws IOException { .containsEntry(FUNCTION_VERSION.getName(), "1") .containsEntry(FUNCTION_NAME.getName(), "test-function") .containsEntry(FUNCTION_REQUEST_ID.getName(), "test-request-id") + .containsEntry(TENANT_ID.getName(), "test-tenant") .containsKey(FUNCTION_COLD_START.getName()) .containsKey(SERVICE.getName()); }