Skip to content

Commit

Permalink
Enable snapstart (#80)
Browse files Browse the repository at this point in the history
* Upgrade dependencies

* Adapt to new api

* Migrate to mui 5

npx @mui/codemod v5.0.0/preset-safe .

* Migrate to mui 5

* Cleanup dependencies

* Deactivate dependabot

* Fix dependencies

* Upgrade GH actions

* Remove unknown eslint rule

* Upgrade dependencies for infrastructure

* Upgrade backend dependencies

* Fix typo

* Replace javax with jakarta annotations

* Enable snapstart for lambdas

* Fix linter warning

---------

Co-authored-by: kaklakariada <kaklakariada@users.noreply.github.com>
  • Loading branch information
kaklakariada and kaklakariada authored Feb 19, 2023
1 parent 4402a27 commit 128a32a
Show file tree
Hide file tree
Showing 13 changed files with 164 additions and 107 deletions.
5 changes: 2 additions & 3 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ dependencies {
implementation "io.micronaut:micronaut-inject"
implementation "io.micronaut:micronaut-validation"
implementation "io.micronaut:micronaut-runtime"
implementation "javax.annotation:javax.annotation-api"
implementation "io.micronaut:micronaut-http-server-netty"
implementation "io.micronaut:micronaut-http-client"

implementation "io.micronaut.crac:micronaut-crac"

implementation "io.micronaut.aws:micronaut-function-aws-api-proxy:$micronautAwsVersion"
implementation "com.amazonaws:aws-java-sdk-ec2:$awsSdkVersion"
implementation "com.amazonaws:aws-java-sdk-dynamodb:$awsSdkVersion"
Expand All @@ -44,7 +44,6 @@ dependencies {

implementation 'ch.qos.logback:logback-classic:1.4.5'
implementation 'io.symphonia:lambda-logging:1.0.3:no-config'
implementation 'javax.inject:javax.inject:1'

testAnnotationProcessor platform("io.micronaut:micronaut-bom:$micronautVersion")
testAnnotationProcessor "io.micronaut:micronaut-inject-java"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

import java.time.Clock;

import javax.inject.Named;
import javax.inject.Singleton;

import org.itsallcode.aws.ec2.dynamodb.DynamoDbTableNameResolver;

import com.amazonaws.regions.Regions;
Expand All @@ -21,6 +18,8 @@
import com.fasterxml.jackson.databind.ObjectMapper;

import io.micronaut.context.annotation.Factory;
import jakarta.inject.Named;
import jakarta.inject.Singleton;

@Factory
public class AwsClientFactory
Expand All @@ -40,9 +39,10 @@ public AmazonDynamoDB dynamoDbClient()
}

@Singleton
public DynamoDBMapper dynamoDbMapper(AmazonDynamoDB client, DynamoDbTableNameResolver tableNameResolver)
public DynamoDBMapper dynamoDbMapper(final AmazonDynamoDB client, final DynamoDbTableNameResolver tableNameResolver)
{
DynamoDBMapperConfig config = DynamoDBMapperConfig.builder().withTableNameResolver(tableNameResolver).build();
final DynamoDBMapperConfig config = DynamoDBMapperConfig.builder().withTableNameResolver(tableNameResolver)
.build();
return new DynamoDBMapper(client, config);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.itsallcode.aws.ec2;

import javax.inject.Singleton;

import org.itsallcode.aws.ec2.model.ResultMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -12,6 +10,7 @@
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.exceptions.HttpStatusException;
import io.micronaut.http.server.exceptions.ExceptionHandler;
import jakarta.inject.Singleton;

@Produces
@Singleton
Expand All @@ -20,14 +19,14 @@ public class GlobalExceptionHandler implements ExceptionHandler<Exception, HttpR
private static final Logger LOG = LoggerFactory.getLogger(InstanceController.class);

@Override
public HttpResponse<ResultMessage<String>> handle(@SuppressWarnings("rawtypes") HttpRequest request,
Exception exception)
public HttpResponse<ResultMessage<String>> handle(@SuppressWarnings("rawtypes") final HttpRequest request,
final Exception exception)
{
LOG.error("Error processing request {}: {}", request, exception, exception);

if (exception instanceof HttpStatusException)
{
HttpStatus status = ((HttpStatusException) exception).getStatus();
final HttpStatus status = ((HttpStatusException) exception).getStatus();
return HttpResponse.status(status, exception.getMessage());
}
return HttpResponse.serverError(new ResultMessage<>(exception.toString()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import java.util.List;

import javax.inject.Inject;

import org.itsallcode.aws.ec2.model.ResultMessage;
import org.itsallcode.aws.ec2.model.SimpleInstance;
import org.itsallcode.aws.ec2.service.InstanceService;
Expand All @@ -22,15 +20,16 @@
import io.micronaut.http.annotation.PathVariable;
import io.micronaut.http.annotation.Put;
import io.micronaut.http.exceptions.HttpStatusException;
import jakarta.inject.Inject;

@Controller("/instances")
public class InstanceController
{
private static final Logger LOG = LoggerFactory.getLogger(InstanceController.class);
private InstanceService instanceService;
private final InstanceService instanceService;

@Inject
public InstanceController(InstanceService instanceService)
public InstanceController(final InstanceService instanceService)
{
this.instanceService = instanceService;
}
Expand All @@ -39,27 +38,27 @@ public InstanceController(InstanceService instanceService)
public HttpResponse<ResultMessage<List<SimpleInstance>>> listInstances()
{
LOG.info("Getting instance list...");
List<SimpleInstance> result = instanceService.list();
final List<SimpleInstance> result = instanceService.list();
return HttpResponse.ok(new ResultMessage<>(result));
}

@Consumes({ MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON })
@Put("/{id}/state/{state}")
public HttpResponse<ResultMessage<String>> startInstance(@PathVariable(name = "id") String id,
@PathVariable(name = "state") String state)
public HttpResponse<ResultMessage<String>> startInstance(@PathVariable(name = "id") final String id,
@PathVariable(name = "state") final String state)
{
LOG.info("Setting instance {} state to {}...", id, state);
if ("start".equals(state))
{
StartInstancesResult result = instanceService.start(id);
String newState = result.getStartingInstances().isEmpty() ? null
final StartInstancesResult result = instanceService.start(id);
final String newState = result.getStartingInstances().isEmpty() ? null
: result.getStartingInstances().get(0).getCurrentState().getName();
return HttpResponse.ok(new ResultMessage<>("Starting instance " + id + ", new state: " + newState));
}
if ("stop".equals(state))
{
StopInstancesResult result = instanceService.stop(id);
String newState = result.getStoppingInstances().isEmpty() ? null
final StopInstancesResult result = instanceService.stop(id);
final String newState = result.getStoppingInstances().isEmpty() ? null
: result.getStoppingInstances().get(0).getCurrentState().getName();
return HttpResponse.ok(new ResultMessage<>("Stopping instance " + id + ", new state: " + newState));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.itsallcode.aws.ec2;

import java.util.List;

import org.crac.Context;
import org.crac.Resource;
import org.itsallcode.aws.ec2.model.SimpleInstance;
import org.itsallcode.aws.ec2.service.InstanceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.micronaut.crac.OrderedResource;
import jakarta.inject.Inject;

public class SnapStartCallback implements OrderedResource
{
private static final Logger LOG = LoggerFactory.getLogger(SnapStartCallback.class);

private final InstanceService instanceService;

@Inject
public SnapStartCallback(final InstanceService instanceService)
{
this.instanceService = instanceService;
}

@Override
public void beforeCheckpoint(final Context<? extends Resource> context)
{
LOG.info("Before checkpoint");
try
{
final List<SimpleInstance> instances = instanceService.list();
LOG.info("Found {} instances", instances.size());
}
catch (final Exception e)
{
LOG.warn("Failed to initialize lambda", e);
}
}

@Override
public void afterRestore(final Context<? extends Resource> context)
{
LOG.info("After restore");
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package org.itsallcode.aws.ec2.dynamodb;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -11,25 +8,27 @@

import io.micronaut.context.env.Environment;
import io.micronaut.core.type.Argument;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;

@Singleton
public class DynamoDbTableNameResolver implements TableNameResolver
{
private static final Logger LOG = LoggerFactory.getLogger(DynamoDbTableNameResolver.class);

private Environment env;
private final Environment env;

@Inject
public DynamoDbTableNameResolver(Environment env)
public DynamoDbTableNameResolver(final Environment env)
{
this.env = env;
}

@Override
public String getTableName(Class<?> clazz, DynamoDBMapperConfig config)
public String getTableName(final Class<?> clazz, final DynamoDBMapperConfig config)
{
String configProperty = "tablename." + clazz.getSimpleName().toLowerCase();
String tableName = env.get(configProperty, Argument.of(String.class))
final String configProperty = "tablename." + clazz.getSimpleName().toLowerCase();
final String tableName = env.get(configProperty, Argument.of(String.class))
.orElseThrow(() -> new IllegalArgumentException("Tablename for class " + clazz.getSimpleName()
+ " not found in environment using property " + configProperty));
LOG.debug("Got table {} for class {} from env property {}", tableName, clazz.getSimpleName(), configProperty);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

import java.util.List;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.itsallcode.aws.ec2.dynamodb.DynamoDbInstance;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression;

import jakarta.inject.Inject;
import jakarta.inject.Singleton;

@Singleton
public class DynamoDbInstanceService
{
private final DynamoDBMapper mapper;

@Inject
public DynamoDbInstanceService(DynamoDBMapper mapper)
public DynamoDbInstanceService(final DynamoDBMapper mapper)
{
this.mapper = mapper;
}
Expand All @@ -26,7 +26,7 @@ public List<DynamoDbInstance> list()
return mapper.scan(DynamoDbInstance.class, new DynamoDBScanExpression());
}

public DynamoDbInstance getInstance(String id)
public DynamoDbInstance getInstance(final String id)
{
return mapper.load(DynamoDbInstance.class, id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
import java.util.Collection;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -23,6 +20,8 @@

import io.micronaut.http.HttpStatus;
import io.micronaut.http.exceptions.HttpStatusException;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;

@Singleton
public class Ec2Service
Expand All @@ -34,7 +33,7 @@ public class Ec2Service
private final boolean startStopAllowed;

@Inject
public Ec2Service(AmazonEC2 ec2Client)
public Ec2Service(final AmazonEC2 ec2Client)
{
this.ec2Client = ec2Client;
this.startStopAllowed = true;
Expand All @@ -45,20 +44,20 @@ public List<Instance> list()
return list(emptyList());
}

private List<Instance> list(Collection<String> ids)
private List<Instance> list(final Collection<String> ids)
{
DescribeInstancesRequest request = new DescribeInstancesRequest();
final DescribeInstancesRequest request = new DescribeInstancesRequest();
if (!ids.isEmpty())
{
request.withInstanceIds(ids);
}
DescribeInstancesResult instances = ec2Client.describeInstances(request);
final DescribeInstancesResult instances = ec2Client.describeInstances(request);
return instances.getReservations().stream() //
.flatMap(res -> res.getInstances().stream()) //
.collect(toList());
}

public StartInstancesResult start(String id)
public StartInstancesResult start(final String id)
{
LOG.info("Starting instance {}...", id);
if (startStopAllowed)
Expand All @@ -68,7 +67,7 @@ public StartInstancesResult start(String id)
throw new HttpStatusException(HttpStatus.FORBIDDEN, "Starting this instance is not allowed");
}

public StopInstancesResult stop(String id)
public StopInstancesResult stop(final String id)
{
LOG.info("Stopping instance {}...", id);
if (startStopAllowed)
Expand Down
Loading

0 comments on commit 128a32a

Please sign in to comment.