Skip to content

Event Handlers

Dennis Vriend edited this page Dec 26, 2017 · 4 revisions

Event Handlers

The component model defines Event Handlers as a compute resource that has been wired to an event-generator resource. At almost every AWS reinvent, AWS announces new kinds of event generators that trigger AWS Lambda's, the compute resource underlying the component model.

Types of Event Handlers

sbt-sam currently supports the following event handlers:

Note: Of course, the annotation must be placed on the appropriate EventHandler to make sense, for example, only annotate a ScheduledEventHandler with @ScheduleConf.

Specialized Event handlers

Event handlers are resource-event-type specialized, meaning that every AWS resource has a specialized event as payload; there is no generic form. This design decision has implications in that, every event handler must be specialized to handle a resource specific event. This means that a ScheduledEventHandler cannot handle an ApiGateway Event.

Event handlers are therefor specialized to handle only one type of events. Sbt-sam uses Scala as the expression language for compute. Scala uses functional and type theory to model a problem and solve it. The specialized event handler design of components combined with the resource-specific-event-generators of AWS, and the functional/type-theory design of Scala implies that only one, specialized type of event can be handled.

Handling typed events

To handle resource specialized events, sbt-sam uses play-json to capture the type that the event handler will process. The strategy on how to process the event is captured by both the specialized event handler, eg. ScheduledEventHandler in combination with a specialized payload in the form of a play.api.libs.json.Format. Components handle messages in the form of records, which are value objects. Scala has support for a record in the form of case classes. Case class that have special meaning in the Scala programming language, and are heavily used for defining rules for transformations belonging to the value object by means of a process called implicit resolution in combination with the type class pattern. This approach is a perfect fit for the design to handle AWS resource specific events.

Configuring Event Handlers

Event Handlers can be configured in two ways:

  • configuring the resource
  • configuring compute

Configuring Resources

Configuring resources can be done by using one of the supported annotations:

HttpHandler

The HttpHandler defines the following properties:

The HttpHandler defines the following properties:

  • path: the path of the Api resource on which compute will be wired to
  • method: the method that will be used by the Api resource that will trigger compute
  • authorization: whether the Api resource must be protected by Cognito User Pools

Every handler defines common properties for compute like:

  • memorySize: the memory size that will be available to compute. This number can be increased by 64MB, from 128MB up to 3008MB. Most simple Scala-based compute need 256MB to operate.
  • timeout: the invocation timeout set for the lambda. Each invocation has a timeout and by default is set to 300 seconds. Every invocation following the previous one starts with the same timeout, which by default is 300 seconds. This value must not be set lower than 60 seconds, because of JVM startup time due to cold start.
  • description: a description for the compute.
@Retention(RetentionPolicy.RUNTIME)
public @interface HttpHandler {
    String path() default "/";
    String method() default "get";
    boolean authorization() default false;
    int memorySize() default 1024;
    int timeout() default 300;
    String description() default "";
}

DynamoHandler

The DynamoHandler defines the following properties:

  • tableName: the logical table name that has been used in the sam.conf configuration. To be clear, given the following configuration, People (uppercase) is the logical table name, and people lowercase, is the table name that must be used for creating repositories. Every table exposes a single event stream and the stream is what will be used to subscribe compute to.
dynamodb {
  People {
    name = people
    hash-key = {
      name = id
      type = S
    }
    stream = KEYS_ONLY // only the key attributes of the modified item.
    rcu = 1
    wcu = 1
  }
}
  • batch size: number of messages that will be delivered to compute in a single message
  • startingPosition: TRIM_HORIZON or LATEST

Every handler defines common properties for compute like:

  • memorySize: the memory size that will be available to compute. This number can be increased by 64MB, from 128MB up to 3008MB. Most simple Scala-based compute need 256MB to operate.
  • timeout: the invocation timeout set for the lambda. Each invocation has a timeout and by default is set to 300 seconds. Every invocation following the previous one starts with the same timeout, which by default is 300 seconds. This value must not be set lower than 60 seconds, because of JVM startup time due to cold start.
  • description: a description for the compute.
@Retention(RetentionPolicy.RUNTIME)
public @interface DynamoHandler {
    String tableName() default "";
    int batchSize() default 100;
    String startingPosition() default "LATEST";
    boolean enabled() default true;
    int memorySize() default 1024;
    int timeout() default 300;
    String description() default "";
}

KinesisConf

The KinesisConf defines the following properties:

  • stream: the name of the stream as defined in sam.conf
  • batch size: number of messages that will be delivered to compute in a single message
  • startingPosition: TRIM_HORIZON or LATEST

Every handler defines common properties for compute like:

  • memorySize: the memory size that will be available to compute. This number can be increased by 64MB, from 128MB up to 3008MB. Most simple Scala-based compute need 256MB to operate.
  • timeout: the invocation timeout set for the lambda. Each invocation has a timeout and by default is set to 300 seconds. Every invocation following the previous one starts with the same timeout, which by default is 300 seconds. This value must not be set lower than 60 seconds, because of JVM startup time due to cold start.
  • description: a description for the compute.
@Retention(RetentionPolicy.RUNTIME)
public @interface KinesisConf {
    String stream() default "";
    int batchSize() default 100;
    String startingPosition() default "LATEST";
    int memorySize() default 1024;
    int timeout() default 300;
    String description() default "";
}

SNSConf

The SNSConf defines the following properties:

  • stream: the name of the topic as defined in sam.conf

Every handler defines common properties for compute like:

  • memorySize: the memory size that will be available to compute. This number can be increased by 64MB, from 128MB up to 3008MB. Most simple Scala-based compute need 256MB to operate.
  • timeout: the invocation timeout set for the lambda. Each invocation has a timeout and by default is set to 300 seconds. Every invocation following the previous one starts with the same timeout, which by default is 300 seconds. This value must not be set lower than 60 seconds, because of JVM startup time due to cold start.
  • description: a description for the compute.
@Retention(RetentionPolicy.RUNTIME)
public @interface SNSConf {
    String topic() default "";
    int memorySize() default 1024;
    int timeout() default 300;
    String description() default "";
}

ScheduleConf

The SNSConf defines the following properties:

Every handler defines common properties for compute like:

  • memorySize: the memory size that will be available to compute. This number can be increased by 64MB, from 128MB up to 3008MB. Most simple Scala-based compute need 256MB to operate.
  • timeout: the invocation timeout set for the lambda. Each invocation has a timeout and by default is set to 300 seconds. Every invocation following the previous one starts with the same timeout, which by default is 300 seconds. This value must not be set lower than 60 seconds, because of JVM startup time due to cold start.
  • description: a description for the compute.
@Retention(RetentionPolicy.RUNTIME)
public @interface ScheduleConf {
    String schedule() default "rate(1 minute)";
    int memorySize() default 1024;
    int timeout() default 300;
    String description() default "";
}