Pubblicato il 30/12/2023 da alnao nella categoria AWS, Java & Spring Boot

La relazione tra AWS è il linguaggio di programmazione Java è sempre stato molto travagliato visto che si tratta di un linguaggio di proprietà della concorrenza ma visto che è uno dei linguaggi più usati al mondo è stato inevitabile al gestore del Cloud permettere l’uso del linguaggio nei vari servizi. In questo articolo vengono riassunti alcune modalità di sviluppo delle lambda function in linguaggio Java. Il titolo di questo articolo fa sorgente immediata un grosso problema problema: le Java Lambda Function (o lambda expression) sono una tecnica per scrivere blocchi di codice anonimi del tipo:

(parameter1, parameter2) -> { codeBlock(); }

questa tecnica non è da confondere con le AWS Lambda Function, servizio specifico per definire blocchi di codice eseguibile in modalità serverless. In questo sito si cerca sempre di distinguere le due cose anche se, avendo lo stesso nome, è impossibile non fare confusione.

Ad oggi, le versioni supportate sono le versioni stabili dalla 8 alla recente 21, in questo articolo si fa riferimento sempre alla versione 8 per retro-compatibilità, per maggior informazioni si rimanda sempre alla documentazione ufficiale dove sono indicati anche i passi per la creazione di AWS Lambda function da console web. Inoltre è disponibile una bellissima libreria SDK per permettere l’integrazione con altri servizi del Cloud, si rimanda sempre alla documentazione ufficiale per maggiori dettagli.

Come per le AWS Lammbda Function scritte negli altri linguaggi, è necessario definire un punto di ingresso detto Handler che quasi sempre viene indicato con un metodo chiamato handleRequest, questo metodo poi definisce la logica di implementazione:

package example;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class HandlerIntegerJava implements RequestHandler<String, String>{
  @Override
  public String handleRequest(String event, Context context){
    LambdaLogger logger = context.getLogger();
    logger.log("EVENT TYPE: " + event.getClass().toString());
    return event.toLowerCase();
  }
}

Nella definizione da console o in maniera programmatica è necessario poi indicare il pacakge e il Handler:


Attraverso l’ambiente di sviluppo MS Visual studio è possibile creare e gestire le AWS Lambda function in maniera veloce ed efficace, è consigliato l’utilizzo dell’estensione ufficiale AWS Toolkit:

che permette di gestire, creare e invocare le AWS Lambda function in combinazione alla CLI e alla CLI-SAM indispensabili per l’utilizzo di questi sistemi.

Per creare una lambda da zero è possibile usare il comando:

> Create lambda SAM application

dalla riga di comando dell’applicazione (Ctrl+Maiusc+P), in questa piccola procedura guidata è possibile selezionare il tipo di linguaggio (java e maven), il modello (consigliato il base HelloWorld) e la cartella dove salvare il progetto. Il generato è un piccolo progetto con i componenti:

  • cartella event con un file json di esempio che permetterà di eseguire i test da locale
  • il file template.yaml con il template completo di cloudformation con la definizione della lambda e la definizione della API tramite gateway
  • il progetto java-maven in una sottocartella con la classe App già pronta per essere eseguita

Da notare che trattandosi di un piccolo template CloudFormation è possibile eseguire il rilascio in AWS con i comandi CLI-SAM:

sam build 
sam deploy --guided 
sam delete --stack-name es03j

Ma è possibile eseguire il rilascio anche con il plugin del programma con il comando:

> AWS deploy sam application

La guida completa del plugin e di tutte le funzionalità disponibili è presente nel sito ufficiale. Bisogna sempre ricordare che è possibile invocare le AWS Lambda function da CLI con il comando:

aws lambda invoke --function-name function_name --payload file://event.json out.json

da console oppure anche dal programma Visual Studio è possibile eseguirle con una semplice interfaccia. Il progetto di esempio creato dal plugin è più complesso rispetto al metodo semplice descritto sopra in quanto questo prevede in request un oggetto proveniente dal ApiGateway e in response un oggetto secondo il formato http standard per il ApiGateway, l’esempio base prevede questa forma:

public APIGatewayProxyResponseEvent handleRequest(
    final APIGatewayProxyRequestEvent input, final Context context) {
  Map<String, String> headers = new HashMap<>();
  headers.put("Content-Type", "application/json");
  headers.put("X-Custom-Header", "application/json");
  APIGatewayProxyResponseEvent response = 
    new APIGatewayProxyResponseEvent().withHeaders(headers);
  try {
    final String pageContents = "hello world";
    String output = String.format("{ \"message\": \"%s\" }", pageContents);
    return response.withStatusCode(200).withBody(output);
  } catch (IOException e) {
    return response.withBody("{}").withStatusCode(500);
  }
}

Il codice di queste semplici AWS Lambda Function scritte in linguaggio Java sono disponibili in un repository specifico:

https://github.com/alnao/AwsLambdaExamples

Negli esempi creati da Visual Studio Code, il plugin genera un template CloudFormation per la gestione delle risorse AWS, in particolare la CLI-SAM provvede anche alla compilazione della classe java e al rilascio delle classi, bisogna ricordare che il file jar deve essere rilasciato in un bucket S3, anche usando la funzionalità del plugin:

> AWS deploy sam application

bisogna indicare il nome del bucket di appoggio. Nel output del comando viene visualizzato lo stato di avanzamento del rilascio e l’esito finale del caricamento.

Con CloudFormation è possibile creare una funzione AWS-Lambda in maniera molto veloce usando maven e i vari modelli messi a disposizione dal framework serverless, in particolare la classe java deve essere definita in un progetto maven con le dipendenze già viste in precedenza. Nel template di definizione delle risorse è possibile definire le varie caratteristiche della funzione e la definizione di un metodo/stage con API-Gateway per esporre la funzione come servizio HTTP-Rest:

HelloWorldFunction:
  Type: AWS::Serverless::Function
  Properties:
    CodeUri: HelloWorldFunction
    Handler: helloworld.App::handleRequest
    Runtime: java8
    Environment:
      Variables:
         PARAM1: VALUE
    Events:
      HelloWorld:
        Type: HttpApi
        Properties:
          ApiId: !Ref ES15HttpApi
          Path: /hello
          Method: GET
ES15HttpApi:
  Type: AWS::Serverless::HttpApi
  Properties:
    StageName: !Ref StageName
    RouteSettings:
      "GET /hello":
        ThrottlingBurstLimit: 500

L’esempio completo è disponibile al solito repository:

https://github.com/alnao/AWSCloudFormationExamples/tree/master/Esempio15lambdaJava
MENU