BaseHandler implements Handler<T> { public void init(Context ctx) throws HandlerException { String alias = null; String[] tokens = ctx.getInvokedFunctionArn().split(":"); if (tokens.length == 7) { alias = "$LATEST"; } else if (tokens.length == 8) { alias = tokens[7]; } BenderLayout.ALIAS = alias; BenderLayout.VERSION = ctx.getFunctionVersion(); monitor = Monitor.getInstance(); monitor.addTag("functionName", ctx.getFunctionName()); monitor.addTag("functionVersion", alias); String configFile; if (System.getenv("BENDER_CONFIG") != null) { configFile = System.getenv("BENDER_CONFIG"); } else if (CONFIG_FILE == null) { configFile = "/config/" + alias; } else { configFile = CONFIG_FILE; } logger.info(String.format("Bender Initializing (config: %s)", configFile)); try { if (configFile.startsWith("s3: config = BenderConfig.load(s3ClientFactory, new AmazonS3URI(configFile)); } else if (configFile.startsWith("file: File file = new File(configFile.replaceFirst("file: String string = FileUtils.readFileToString(file); config = BenderConfig.load(configFile, string); } else { config = BenderConfig.load(configFile); } } catch (ConfigurationException | IOException e) { throw new HandlerException("Error loading configuration: " + e.getMessage(), e); } HandlerResources handlerResources; try { handlerResources = new HandlerResources(config); } catch (ClassNotFoundException e) { throw new HandlerException("Unable to load resource: " + e.getMessage(), e); } monitor.addTags(config.getHandlerConfig().getMetricTags()); if (config.getHandlerConfig().getIncludeFunctionTags()) { AWSLambda lambda = this.lambdaClientFactory.newInstance(); ListTagsResult res = lambda.listTags(new ListTagsRequest().withResource(ctx.getInvokedFunctionArn())); monitor.addTagsMap( res.getTags().entrySet().stream() .filter(map -> !map.getKey().startsWith("aws:cloudformation")) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); } monitor.addReporters(handlerResources.getReporters()); wrapper = handlerResources.getWrapperFactory().newInstance(); ser = handlerResources.getSerializerProcessor(); setIpcService(new IpcSenderService(handlerResources.getTransportFactory())); sources = new ArrayList<Source>(handlerResources.getSources().values()); queueSize = config.getHandlerConfig().getQueueSize(); initialized = true; }  void init(Context ctx); void process(Context context); void shutdown(); IpcSenderService getIpcService(); void setIpcService(IpcSenderService ipcService); static String CONFIG_FILE; }
@Test public void testLambdaFunctionTags() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config_tags.json"; TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:test_tags"); AWSLambdaClientFactory mockFactory = mock(AWSLambdaClientFactory.class); AWSLambda mockLambda = mock(AWSLambda.class); doReturn(mockLambda).when(mockFactory).newInstance(); ListTagsResult mockResult = mock(ListTagsResult.class); HashMap<String, String> expected = new HashMap<String, String>() { { put("t1", "foo"); put("t2", "bar"); } }; doReturn(expected).when(mockResult).getTags(); doReturn(mockResult).when(mockLambda).listTags(any()); handler.lambdaClientFactory = mockFactory; handler.init(context); Map<String, String> actual = handler.monitor.getTagsMap(); assertTrue(actual.entrySet().containsAll(expected.entrySet())); }
@Test public void testUserTags() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config_user_tags.json"; TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:test_tags"); HashMap<String, String> expected = new HashMap<String, String>() { { put("u1", "foo"); put("u2", "bar"); } }; handler.init(context); Map<String, String> actual = handler.monitor.getTagsMap(); assertTrue(actual.entrySet().containsAll(expected.entrySet())); }
@Test public void tagsDuplicate() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config_tags_duplicate.json"; TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:test_tags"); AWSLambdaClientFactory mockFactory = mock(AWSLambdaClientFactory.class); AWSLambda mockLambda = mock(AWSLambda.class); doReturn(mockLambda).when(mockFactory).newInstance(); ListTagsResult mockResult = mock(ListTagsResult.class); HashMap<String, String> functionTags = new HashMap<String, String>() { { put("f1", "foo"); put("f2", "foo"); } }; doReturn(functionTags).when(mockResult).getTags(); doReturn(mockResult).when(mockLambda).listTags(any()); handler.lambdaClientFactory = mockFactory; handler.init(context); Map<String, String> actual = handler.monitor.getTagsMap(); HashMap<String, String> expected = new HashMap<String, String>() { { put("f1", "foo"); put("f2", "foo"); put("u1", "bar"); } }; assertTrue(actual.entrySet().containsAll(expected.entrySet())); }
@Test public void tagsCloudformation() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config_tags_duplicate.json"; TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:test_tags"); AWSLambdaClientFactory mockFactory = mock(AWSLambdaClientFactory.class); AWSLambda mockLambda = mock(AWSLambda.class); doReturn(mockLambda).when(mockFactory).newInstance(); ListTagsResult mockResult = mock(ListTagsResult.class); HashMap<String, String> functionTags = new HashMap<String, String>() { { put("f1", "foo"); put("aws:cloudformation:foo", "foo"); put("aws:cloudformation:bar", "bar"); } }; doReturn(functionTags).when(mockResult).getTags(); doReturn(mockResult).when(mockLambda).listTags(any()); handler.lambdaClientFactory = mockFactory; handler.init(context); Map<String, String> actual = handler.monitor.getTagsMap(); HashMap<String, String> expected = new HashMap<String, String>() { { put("f1", "foo"); put("u1", "bar"); } }; assertTrue(actual.entrySet().containsAll(expected.entrySet())); }
@Test public void testDeserializationException() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config.json"; handler.skipWriteStats = true; List<DummyEvent> events = new ArrayList<DummyEvent>(1); events.add(new DummyEvent("foo", 0)); TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:tag"); handler.init(context); DeserializerProcessor proc = handler.sources.get(0).getDeserProcessor(); Deserializer deserSpy = spy(proc.getDeserializer()); doThrow(new DeserializationException("expected")).when(deserSpy).deserialize(anyString()); proc.setDeserializer(deserSpy); handler.handler(events, context); assertEquals(1, proc.getErrorCountStat().getValue()); }
@Test public void testFilterFailedDeserialization() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config.json"; handler.skipWriteStats = true; List<DummyEvent> events = new ArrayList<DummyEvent>(1); events.add(new DummyEvent("foo", 0)); TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:tag"); handler.init(context); DeserializerProcessor proc = handler.sources.get(0).getDeserProcessor(); Deserializer deserSpy = spy(proc.getDeserializer()); doThrow(new DeserializationException("expected")).when(deserSpy).deserialize(anyString()); proc.setDeserializer(deserSpy); handler.handler(events, context); assertEquals(0, BufferedTransporter.output.size()); }
@Test public void testFilterNullDeserialization() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config.json"; handler.skipWriteStats = true; List<DummyEvent> events = new ArrayList<DummyEvent>(1); events.add(new DummyEvent("foo", 0)); TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:tag"); handler.init(context); DeserializerProcessor proc = handler.sources.get(0).getDeserProcessor(); Deserializer deserSpy = spy(proc.getDeserializer()); when(deserSpy.deserialize(anyString())).thenReturn(null); proc.setDeserializer(deserSpy); handler.handler(events, context); assertEquals(0, BufferedTransporter.output.size()); }
@Test public void testSerializationException() throws HandlerException, SerializationException { BaseHandler.CONFIG_FILE = "/config/handler_config.json"; handler.skipWriteStats = true; List<DummyEvent> events = new ArrayList<DummyEvent>(1); events.add(new DummyEvent("foo", 0)); TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:tag"); handler.init(context); Serializer serSpy = spy(handler.ser.getSerializer()); doThrow(new DeserializationException("")).when(serSpy).serialize(any()); handler.ser.setSerializer(serSpy); handler.handler(events, context); assertEquals(1, handler.ser.getErrorCountStat().getValue()); }
@Test public void testOperationException() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config.json"; handler.skipWriteStats = true; List<DummyEvent> events = new ArrayList<DummyEvent>(1); events.add(new DummyEvent("foo", 0)); TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:tag"); handler.init(context); List<OperationProcessor> operationProcessors = handler.sources.get(0).getOperationProcessors(); for (OperationProcessor operationProcessor : operationProcessors) { EventOperation operation = (EventOperation) spy(operationProcessor.getOperation()); doThrow(new OperationException("expected")).when(operation).perform(any()); operationProcessor.setOperation(operation); } handler.handler(events, context); assertEquals(1, operationProcessors.get(0).getErrorCountStat().getValue()); }
@Test public void testMultipleOperationsConfig() throws HandlerException { BaseHandler.CONFIG_FILE = "/config/handler_config_two_operations.json"; List<DummyEvent> events = new ArrayList<DummyEvent>(1); events.add(new DummyEvent("foo", 0)); TestContext context = new TestContext(); context.setInvokedFunctionArn("arn:aws:lambda:us-east-1:123:function:test:tag"); handler.init(context); List<OperationProcessor> operationProcessores = handler.sources.get(0).getOperationProcessors(); for (int i = 0; i < operationProcessores.size(); i++) { OperationProcessor operationProcessor = spy(operationProcessores.get(i)); operationProcessores.set(i, operationProcessor); } handler.handler(events, context); verify(operationProcessores.get(0), times(1)).perform(any()); verify(operationProcessores.get(1), times(1)).perform(any()); }