How can I access the lambda execution context from within a Quarkus REST API? - aws-lambda

A regular Lambda handler has it, but in the Quarkus generated JAX-RS handler I cannot find a way to access it. I assume there should be a way to inject it or something... Why I'm asking? I would like to read the lambda execution ID to pass it back, so I can check when this particular execution has ended - without the extra work of creating extra resources (including step functions) or database flags.

It depends on which context you want and which dependency / API Gateway you use.
For lambda context you can use:
#Path("/myresource")
public class MyResource {
#GET
public String ctx(#Context com.amazonaws.services.lambda.runtime.Context ctx) { }
}
See: https://quarkus.io/guides/amazon-lambda-http#injectable-aws-context-variables

Related

Spring Boot + Apache Camel + AWS Lambda with multiple lambda endpoints

I am learning Apache Camel and how to use it with Spring Boot. I have been able to successfully hit one lambda function using Camel and Spring and so far it works great. However I'm having trouble when I try to add a second function that I want to hit using a different route.
At a core, the problem I'm having is that it seems Camel requires that the property camel.component.aws-lambda.configuration.function is defined in order to create an endpoint. But obviously I don't want to define that property because I need to have multiple functions, not just a single one.
Current code that works:
application.yaml:
camel:
component:
aws-lambda:
configuration:
access-key: myAccessKey
secret-key: mySecretKey
region: MY_REGION
function: myFunction
operation: invokeFunction
My route:
#Component
public class MessageTestInvocationRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("somewhere").routeId("lambda")
.to("aws-lambda://myFunction");
}
}
Now how can I add a second route? As soon as I comment out the camel.component.aws-lambda.configuration.function property, my existing route breaks due to an NPE. But if I leave that property defined, then it seems all AWS calls will be tied to that one function.
I have tried looking into making custom LambdaComponents, I have tried looking into making custom AWSLambdaClients, none of these did anything useful - it all falls apart as soon as I comment out that property.
I figured it out. The reason I was getting an NPE is because I did not have an operation defined. When the function and operation are defined in application.yaml, then Spring attempts to use that one, which is why commenting out those properties caused that issue. The solution was to comment out the function and operation properties, and then change my route code to:
#Component
public class MessageTestInvocationRoute extends RouteBuilder {
#Override
public void configure() throws Exception {
from("somewhere").routeId("lambda")
.to("aws-lambda://myFunction?operation=invokeFunction");
}
}
Now I am able to create multiple routes that all function just fine in parallel.

Spring service with in-memory list

I want to have a service which keeps a list inmemory so I don't need to access the database everytime. The service is accessed by a controller. Is this a valid approach or am I missing something? What about concurrent access here (from the controller)? Is this (stateful service) an anti-pattern?
#Service
public class ServiceCached {
private List<SomeObject> someObjects;
#PostConstruct
public void initOnce() {
someObjects = /** longer running loading methodd **/
}
public List<SomeObject> retrieveObjects() {
return someObjects;
}
}
Thanks!
I wouldn't call it an anti-pattern, but in my opinion loading the list from the database in a #PostConstruct method is not a good idea as you slow down the start up of your application, I'd rather use a lazy loading mechanism, but this would potentially introduce some concurrent access issues that would need to be handled.
In your example concurrent access from the controller should not be a problem as the list is loaded from a #PostConstruct method and the controller would depend on this service, therefore this service would need to be fully constructed before it is injected into the controller, therefore the list would already be loaded.
Preferably I'd suggest using Spring Caching: Caching Data with Spring, Documentation, Useful guide
Usage example:
#Cacheable("books")
public Book getByIsbn(String isbn) {
simulateSlowService();
return new Book(isbn, "Some book");
}
This way you do not need to take care of loading and evicting the objects. Once set up, the caching framework will take care of this for you.

EntityFrameworkCore - Diagnosing "The connection was not closed. The connection's current state is open."

We seem to have done something to introduce some kind of threading issue into our app. It's a dotnet core 1.1.2 application, using EntityFrameworkCore. Intermittently, but reproducably, we will get one of these errors:
System.InvalidOperationException: 'The connection was not closed. The connection's current state is open.' exception when running an EF query.
or
System.InvalidCastException: 'Unable to cast object of type 'System.Data.ProviderBase.DbConnectionClosedConnecting' to type 'System.Data.SqlClient.SqlInternalConnectionTds'.'
or
System.ObjectDisposedException: 'Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.'
This can happen at almost any point in the app, but this method seems to be the most frequent culprit (this does get called somewhat frequently):
public class WidgetConfigurationRepository : IWidgetConfigurationRepository
{
public WidgetConfigurationRepository(LocalContext dataContext)
{
Context = dataContext ?? throw new ArgumentNullException(nameof(dataContext));
}
private LocalContext _context { get; private set; }
public async Task<WidgetConfiguration> LoadConfigurationAsync(Guid widgetId)
{
return await _context.WidgetConfigurations
.Include(x => x.Options)
.FirstOrDefaultAsync(x => x.WidgetId.Equals(widgetId));
}
...
}
the repository is created via the Core DI container, and is injected at runtime:
services.AddScoped<IWidgetConfigurationRepository, WidgetConfigurationRepository>();
The Repository and the LocalContext are both registered as Scoped, and there are no Singleton accessors of the LocalContext.
Walking through the stack trace (and the parallel stacks) shows that every async method is awaited, and I have gone through replacing the interfaces in the application with the implementations, to hopefully try to find any async without await.
The LocalContext itself is created via a LocalDbContextFactory that is also registered as Scoped. It reads data from a central data context, checks some data and then instantiates a new instance of the LocalContext. This is only happening once per request, as expected.
Ultimately, I'm looking for some help working out what could be causing this, our app is now fairly large and I'm not sure I can provide enough code snippets to help.
At the moment, I think my best option is to write a Roslyn analyzer to go through all the methods that return Task or Task<T> and check that something happens with the return object, but I'm wondering if there is something easier that I may have missed.
There is this related question: EF. The connection was not closed. The connection's current state is connecting
with the
Re-check that IUserService is registered with "scope" lifetime, and all it dependencies (userManager, dbContext) too
Do not use IServiceProvider you obtained during app startup for scope-bases services resolution - it is NOT related to current request scope and return instances from "some other universe". Use HttpContext.RequestServices for service resolution.
Check that your are "awaiting" all async methods. If you start second request while still executing first one - you may possibly "catch" dbContext during "connecting" stage.
Your JwtMessageHandler instance is one/single per app. So don't use it's property for storing _userService (remove private IUserService _userService). Instead, use local variable inside OnMessageReceived (var _userService = ...).
As far as I can tell, we are not being caught by any of these, almost all of our services are Scoped or Transient.
We use ServiceProvider.GetService<>() during the app startup, to resolve the database to run Migrations on, but not beyond that.
I think it's possible that there is an async without an await, but I don't seem to be able to find it, and we aren't getting compiler warnings for it.

Spring controller method invocation advice

I have a controller that exposes the following endpoint:
#RequestMapping("/all-users")
List<User> getAllUsers() {
...
}
I have also an annotation that helps me out with versioning of those endpoints, which ends up on something like this:
#RequestMapping("/all-users")
#Version(version=1, latests=LATEST_ALL_USERS)
List<User> getAllUsers() {
...
}
Now I want to introduce an additional standard behavior to all handlers mapped wish method contains #Version annotation which will simply wrap the response object into another object which contains the current version and latest version of the invoked method. Some information to build this object are provided by #PathVariable parameters. I'm trying to find a hook that allows me that but no luck so far.
I tried first to have a custom RequestResponseBodyMethodProcessor but if I add it will not take any effect because the original RequestResponseBodyMethodProcessor comes before and I don't want to remove the ResponseBody from my endpoints.
Afterward I tried to go for the mapping instead, once I cannot handle it on the processor, maybe I could handle that on mapping time introducing my code pre and post method invocation, but got stuck on the point where mapping is registered where a method object is needed, not allowing me to introduce my advice code.
Is there any way to get this done?
Edit:
Some of the information needed to build the new returned object are provided as #PathVariables, and are available on end-point method call.

Is there any way to intercept all Linq to SQL queries?

I've built some code that can rebuild expression trees so I can avoid triggering the no supported translation to SQL exception and it works fine as long as I call my function to replace the iqueryable. The problem is that I'd like it to automatically be applied to all queries in my project without having to worry about calling this function on each one separately. Is there any way that I can intercept everything?
I've tried using Reflection.Emit to create a wrapping provider and using reflection to replace it on the data context and it turns out that even with Reflection.Emit I can't implement the internal IProvider interface.
I've also tried replacing the provider with a RealProxy based class and that works for non-compiled queries, but the CompiledQuery.Execute method is throwing an exception because it won't cast to the SqlProvider class. I tried replacing the response to the Compile method on the provider with another proxy so I could intercept the Execute call, but that failed a check on the return type being correct.
I'm open to any other ideas or ways of using what I've already tried?
It's hard to tell whether this is an applicable solution without seeing your code, but if you have a DI-friendly app architecture you can implement an interceptor and have your favorite IoC container emit the appropriate type for you, at run-time.
Esoteric? A little. Consider an interface like this:
public interface ISomeService
{
IEnumerable<SomeEntity> GetSomeEntities();
// ...
}
This interface might be implemented like this:
public class SomeService : ISomeService
{
private readonly DbContext _context // this is a dependency!
private readonly IQueryTweaker _tweaker; // this is a dependency!
public SomeService(DbContext context, IQueryTweaker tweaker) // this is constructor injection!
{
_context = context;
_tweaker = tweaker;
}
public IEnumerable<SomeEntity> GetSomeEntities()
{
return _tweaker.TweakTheQuery(_context.SomeEntities).ToList();
}
}
Every time you implement a method of the ISomeService interface, there's always a call to _tweaker.TweakTheQuery() that wraps the IQueryable, and that not only gets boring, it also feels like something is missing a feature - the same feeling you'd get by wrapping every one of these calls inside a try/catch block, or if you're familiar with MVVM in WPF, by raising this annoying PropertyChanged event for every single property setter in your ViewModel.
With DI Interception, you factor this requirement out of your "normal" code and into an "interceptor": you basically tell the IoC container that instead of binding ISomeService directly to the SomeService implementation, you're going to be decorating it with an interceptor, and emit another type, perhaps SomeInterceptedService (the name is irrelevant, the actual type only exists at run-time) which "injects" the desired behavior into the desired methods. Simple? Not exactly.
If you haven't designed your code with DI in mind (are your dependencies "injected" into your classes' constructor?), it could mean a major refactoring.
The first step breaks your code: remove the IQueryTweaker dependency and all the TweakTheQuery calls from all ISomeService implementations, to make them look like this - notice the virtualness of the method to be intercepted:
public class SomeService : ISomeService
{
private readonly DbContext _context
public SomeService(DbContext context)
{
_context = context;
}
public virtual IEnumerable<SomeEntity> GetSomeEntities()
{
return _context.SomeEntities.ToList();
}
}
The next step is to configure the IoC container so that it knows to inject the SomeService implementation whenever a type's constructor requires an ISomeService:
_kernel.Bind<ISomeService>().To<SomeService>();
At that point you're ready to configure the interception - if using Ninject this could help.
But before jumping into that rabbit's hole you should read this article which shows how decorator and interceptor are related.
The key point is, you're not intercepting anything that's internal to LINQ to SQL or the .NET framework itself - you're intercepting your own method calls, wrapping them with your own code, and with a little bit of help from any decent IoC container, you'll be intercepting the calls to methods that call upon Linq to SQL, rather than the direct calls to Linq to SQL itself. Essentially the IQueryTweaker dependency becomes a dependency of your interceptor class, and you'll only code its usage once.
An interesting thing about DI interception, is that interceptors can be combined, so you can have a ExecutionTimerServiceInterceptor on top of a AuditServiceInterceptor, on top of a CircuitBreakerServiceInterceptor... and the best part is that you can configure your IoC container so that you can completely forget it exists and, as you add more service classes to the application, all you need to do is follow a naming convention you've defined and voilĂ , you've just written a service that not only accomplishes all the strictly data-related tasks you've just coded, but also a service that will disable itself for 3 minutes if the database server is down, and will remain disabled until it's back up; that service also logs all inserts, updates and deletes, and stores its execution time in a database for performance analysis. The term automagical seems appropriate.
This technique - interception - can be used to address cross-cutting concerns; another way to address those is through AOP, although some articles (and Mark Seeman's excellent Dependency Injection in .NET) clearly demonstrate how AOP frameworks are a less ideal solution over DI interception.

Resources