Jusqu'à ce que l'objet S3 soit INSERT dans EC2 DB avec Lambda @ java: Java [Partie 2]

introduction

Cet article rappelle ce qu'AWS, java (presque) débutants ont fait avant d'insérer des objets S3 dans la base de données d'EC2 (SQL Server) avec Lambda @ java. Ceci est la dernière édition de la première trilogie post. Si vous faites remarquer que c'est mieux ici, s'il vous plaît! !!

1: Édition AWS 2: Java [Partie 1] 3: partie Java [Partie 2] <-Partie principale 3.5: Édition Java [suite]

La dernière fois, j'ai confirmé que je pouvais obtenir le nom du fichier que j'ai téléchargé dans le compartiment S3. Maintenant, envoyons un e-mail avec le nom de fichier que vous avez reçu la dernière fois.

Au fait, cette fois, j'ai essayé d'utiliser le package Javax Mail.

Modifier pom.xml

Ajoutez la description suivante aux dépendances dans pom.xml.

<dependency>
  <groupId>com.sun.mail</groupId>
  <artifactId>javax.mail</artifactId>
  <version>1.5.4</version>
</dependency>

envoyer un e-mail

Modifiez la méthode listingNames de la classe ReadS3Object comme suit:

ReadS3Object.java


@SuppressWarnings("deprecation")
public void listingNames(Context context )
{
    AmazonS3 client = new AmazonS3Client(
    		new BasicAWSCredentials(
                    "<accessKey>",
                    "<secretKey>"));
    	
    ListObjectsRequest request = new ListObjectsRequest()
            .withBucketName("test-bucket-yut0201");
    ObjectListing objectList = client.listObjects(request);

    //Obtenez une liste d'objets et affichez le nom de l'objet dans la console
    List<S3ObjectSummary> objects = objectList.getObjectSummaries();
    //System.out.println("objectList:");
    //objects.forEach(object -> System.out.println(object.getKey()));
    	
    List<String> objectNameList = new ArrayList<String>();
    objects.forEach(object -> objectNameList.add(object.getKey()));
    sendMailTest(objectNameList);
}

Je n'ai pas besoin de la sortie vers la console, je l'ai donc commentée et stockée dans une liste de type String à la place. Puisque le courrier est envoyé par la méthode sendMailTest (), implémentons le contenu immédiatement.

ReadS3Object.java


public void sendMailTest(List<String> objectNames) {
		final String fromAddr = "<fromMailAddress>";
		final String toAddr   = "<toMailaddress>";
		final String subject  = "test Mail Send";
		final String charset  = "UTF-8";
		String content  = "S3 object List : ";
		content += String.join(",", objectNames);
		final String encoding = "base64";
		
		final Properties properties = new Properties();

        //Informations de base. Voici un exemple de connexion à nifty.
        properties.setProperty("mail.smtp.host", "smtp.gmail.com");
        properties.setProperty("mail.smtp.port", "587");
        
        //Réglage du délai d'expiration
        properties.setProperty("mail.smtp.connectiontimeout", "60000");
        properties.setProperty("mail.smtp.timeout", "60000");

        //Authentification
        properties.setProperty("mail.smtp.auth", "true");
        properties.setProperty("mail.smtp.starttls.enable", "true");

        final Session session = Session.getInstance(properties, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("<fromMailAddress>", "<password>");
            }
        });
        
        try {
            MimeMessage message = new MimeMessage(session);

            // Set From:
            message.setFrom(new InternetAddress(fromAddr, "<userName>"));
            // Set ReplyTo:
            message.setReplyTo(new Address[]{new InternetAddress(fromAddr)});
            // Set To:
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(toAddr));

            message.setSubject(subject, charset);
            message.setText(content, charset);

            message.setHeader("Content-Transfer-Encoding", encoding);

            Transport.send(message);

          } catch (MessagingException e) {
            throw new RuntimeException(e);
          } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
          }
	}

Définissez les adresses source et de destination pour fromAddr et toAddr. Puisque nous utilisons l'adresse Gmail cette fois, nous avons défini l'adresse Gmail du serveur SMTP. Dans le contenu, les noms des objets sont concaténés après la chaîne, séparés par des virgules, en fonction du nombre d'objets.

Le délai d'expiration est de 60 000 millisecondes pour la connexion et la transmission, mais toute valeur peut être définie dans la plage de 0 à 2147483647.

En outre, Gmail doit effectuer une authentification SMTP pour empêcher le relais tiers, de sorte que les informations d'authentification sont ajoutées aux propriétés. Les arguments de PasswordAuthentication () sont l'ID (adresse e-mail) et le mot de passe du compte Gmail.

Puis, dans cet état, reconditionnez à nouveau dans jar par [Run] -> [S3toLambda].

Note) S3toLambda est la configuration d'exécution qui a été configurée lors de la version précédente de Maven, et l'objectif est "package ombre: ombre".

Après avoir téléchargé le fichier jar sur Lambda, cliquez sur Tester. Si vous pouvez vous connecter au compte Gmail avec l'adresse de destination et confirmer que le courrier est arrivé dans votre boîte de réception, vous avez réussi.

Modifications de la stratégie de rôle Lambda

Lors de l'exécution de la fonction Lambda, je souhaite pouvoir vérifier la fin normale / anormale du résultat de l'exécution dans le journal. Donnons au rôle d'exécution Lambda lambda_s3_exec_role l'autorisation d'écriture pour CloudWatch Logs.

Tout d'abord, connectez-vous à la console de gestion IAM.

Sélectionnez Rôle dans la barre de navigation sur le côté gauche de l'écran et cliquez sur le lambda_s3_exec_role précédemment créé. Certaines stratégies sont fournies par AWS par défaut, mais cette fois, je vais créer une stratégie en ligne (il est pratique de s'en souvenir car elle peut être personnalisée). Cliquez sur "Créer une stratégie en ligne" sur le côté droit de l'écran pour afficher l'écran suivant.

02_create_policy.png

Sélectionnez l'onglet JSON et copiez la description suivante.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "logs:*",
            "Resource": "*"
        }
    ]
}

Note) En ce qui concerne "Version", il semble indiquer la version du format du côté AWS, alors laissez-la telle quelle sans la changer.

À propos, la description ci-dessus est un état d'accès complet qui "Autorise toutes les actions (lecture / écriture) pour toutes les ressources (groupe de journaux, flux de journaux, etc.) de CloudWatch Logs". Si vous souhaitez limiter les autorisations, apportez diverses modifications et essayez-les.

Vérifiez le journal

À ce stade, écrivons le code pour générer le journal. Créez une nouvelle classe sous le package créé la dernière fois.

DetectS3Event.java


package S3test.S3toLambda;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.S3Event;
import com.amazonaws.services.s3.event.S3EventNotification.S3EventNotificationRecord;

public class DetectS3Event implements RequestHandler<S3Event, Object>
{
    @Override
    public Object handleRequest(S3Event event, Context context) {
        context.getLogger().log("Input: " + event);
        LambdaLogger lambdaLogger = context.getLogger();
		
        S3EventNotificationRecord record = event.getRecords().get(0);
        lambdaLogger.log(record.getEventName()); 				//Nom de l'événement
        lambdaLogger.log(record.getS3().getBucket().getName()); //Nom du godet
        lambdaLogger.log(record.getS3().getObject().getKey()); 	//Clé d'objet (nom d'objet)
	
        return null;
    }
}

Détectez un événement sur S3 et obtenez le nom de l'événement, le nom du compartiment cible et le nom de l'objet cible Sortons-le sous forme de journal par Lambda Logger.

Une fois que vous avez emballé votre build Mavan dans un bocal, téléchargez-le sur Lambda. Modifiez le gestionnaire en conséquence. Après avoir cliqué sur [Enregistrer], définissez l'événement de test dans la liste déroulante à gauche de [Test].

Avec "Créer un nouvel événement de test" sélectionné, sélectionnez "S3 Put" ou "S3 Delete" dans le modèle d'événement. Enregistrez-le avec un nom d'événement de test arbitraire. 03_S3_testEvent.png Dans cet état, exécutez [Test] pour confirmer que le résultat de l'exécution est réussi, puis jetez un œil au journal. 04_lambda_result.png 05_cloudwatch_logs_01.png Vous pouvez voir que le journal a été créé dans le flux de journaux, développons-le donc. 06_cloudwatch_logs_02.png Vous savez maintenant que vous avez obtenu avec succès les informations d'événement de test.

Paramètres de déclenchement d'événement

Depuis que j'ai pu confirmer la sortie des informations sur les données de test dans le journal, j'ai en fait déclenché l'événement "Télécharger le fichier" Sortons le journal sur CloudWatch.

Cette fois, définissez l'événement depuis la console de gestion S3 (le paramétrage du côté Lambda est également possible).

Sélectionnez le compartiment souhaité et cliquez sur l'onglet Propriétés. Assurez-vous qu'aucun événement n'est enregistré dans le bloc [Événements] et utilisez [+ Ajouter une notification] pour créer l'événement suivant. 07_S3_create_event.png

Consultez le journal des événements

Dans cet article -Ne pas créer de sous-dossiers dans le seau ・ Télécharger un fichier CSV En raison de la restriction, le préfixe est vide et le suffixe est ".csv".

Après avoir défini l'événement, modifiez handleRequest (événement S3Event, contexte de contexte).

DetectS3Event.java


package S3test.S3toLambda;

//importation omise

public class DetectS3Event implements RequestHandler<S3Event, Object>
{
    @Override
    public Object handleRequest(S3Event event, Context context) {
        context.getLogger().log("Input: " + event);
        LambdaLogger lambdaLogger = context.getLogger();
		
        S3EventNotificationRecord record = event.getRecords().get(0);
		
        String bucketName = record.getS3().getBucket().getName();
        String key = record.getS3().getObject().getKey();
        
        try {
            @SuppressWarnings("deprecation")
            AmazonS3 client = new AmazonS3Client(
            new BasicAWSCredentials("<accessKey>","<secretKey>"));
			
            GetObjectRequest request = new GetObjectRequest(bucketName, key);
            S3Object object = client.getObject(request);
			
            BufferedInputStream bis = new BufferedInputStream(object.getObjectContent());
            BufferedReader br = new BufferedReader(new InputStreamReader(bis));
			
            String line = "";
            while ((line = br.readLine()) != null) {
                String[] data = line.split(",", 0); //Convertir les lignes en un tableau séparé par des virgules

                for (String elem : data) {
                    System.out.println(elem);
                }
            }
            br.close();
        } catch (IOException e) {
            System.out.println(e);
        }
        return null;
    }
}

À titre de test, avec le fichier jar empaqueté dans l'état source ci-dessus téléchargé sur Lambda, Téléchargez le CSV préparé à l'avance comme indiqué ci-dessous. 08_create_csv.png

télécharger. 09_csv_upload.png

Ensuite, avec ce téléchargement comme déclencheur, -S3 lance la fonction Lambda-> La fonction Lambda écrit le résultat de l'exécution dans CloudWatch Logs en fonction du rôle d'exécution Est né.

Il semble y avoir un décalage de plusieurs minutes jusqu'à ce que tous les journaux soient sortis (je ne l'ai pas vérifié avec précision cette fois), mais jetons un coup d'œil aux journaux CloudWatch. 10_logs.png J'ai trouvé que le CSV téléchargé était sorti ligne par ligne, séparés par des virgules, entre les 6ème et 23ème lignes du journal.

Enfin, essayez à nouveau d'utiliser le CSV ci-dessus pour INSÉRER dans la base de données (SQL Server) sur EC2.

Création de bases de données et d'utilisateurs

Remarque) SQL Server Express Edition est supposé être installé. Vous pouvez l'installer en vous référant à Official.

Tout d'abord, connectons-nous à l'instance EC2 créée avec la commande suivante.

ssh -i "<keyPair>" <userName>@<IPaddress>

La paire de clés utilisée en même temps que l'instance EC2 est créée. Si vous utilisez une paire de clés existante, c'est très bien. L'adresse IP sera l'adresse IP Elastic attribuée à l'instance EC2. Vous pouvez vérifier la commande de connexion elle-même avec le bouton [Connect] sur la console de gestion EC2.

Une fois connecté à l'instance, connectez-vous à SQL Server.

sqlcmd -S localhost -U SA

Si l'invite change en quelque chose comme 1>, la connexion est réussie. Ensuite, créons une base de données, des utilisateurs administratifs et des tables.

Créer une base de données

Exécutez la commande suivante. Cette fois, j'utilise SQL Operations Studio.

USE master
GO
IF NOT EXISTS (
   SELECT name
   FROM sys.databases
   WHERE name = N'LambdaTestDB'
)
CREATE DATABASE [LambdaTestDB]
GO

ALTER DATABASE [LambdaTestDB] SET QUERY_STORE=ON
GO

Confirmez que la base de données a été créée normalement.

select name, dbid, mode, status from sysdatabases;
go
name                                                                                                                             dbid   mode   status     
-------------------------------------------------------------------------------------------------------------------------------- ------ ------ -----------
master                                                                                                                                1      0       65544
tempdb                                                                                                                                2      0       65544
model                                                                                                                                 3      0       65536
msdb                                                                                                                                  4      0       65544
LambdaTestDB                                                                                                                          5      0       65537

(5 rows affected)

Ensuite, créez une table dans le LambdaTestDB créé.

USE LambdaTestDB
GO
CREATE TABLE employee (
  emp_id INT NOT NULL PRIMARY KEY,
  emp_name VARCHAR(20) NOT NULL,
  age    INT)
GO

Remarque) Si une erreur s'affiche, résolvez-la en conséquence.

Confirmez que la table a été créée avec succès.

select name, object_id, type_desc from sys.objects where type = 'U'
go
name                                                                                    object_id   type_desc                                                   
--------------------------------------------------------------------------------------- ----------- ------------------------------------------------------------
employee                                                                                  885578193 USER_TABLE                                                  

(1 rows affected)

Si le résultat ci-dessus est obtenu, la création de la table est réussie.

Maintenant que la table à INSÉRER a été créée, rééditez également la source.

Résumé! ??

Cet article a été écrit comme le troisième ouvrage en trois parties, mais au début, le volume du troisième ouvrage était difficile car je ne pensais pas à la composition en particulier. .. .. (excuses) C'est pourquoi je publierai la suite en tant que 3.5ème œuvre plus tard.

Je vous remercie.

Recommended Posts

Jusqu'à ce que l'objet S3 soit INSERT dans EC2 DB avec Lambda @ java: Java [Partie 2]
Jusqu'à INSERT S3 objet dans EC2 DB avec Lambda @ java: Java [Partie 1]
Jusqu'à INSERT S3 objet dans EC2 DB avec Lambda @ java: AWS
Jusqu'à ce que l'objet S3 soit INSERT dans EC2 DB avec Lambda @ java: Java [Suite]
AWS Lambda (Lambda) Partie 1 avec Java pour démarrer maintenant
[Java] Les insertions Batch Insert sont combinées en une seule lorsque vous utilisez MySQL DB dans Doma.
Insertion des données du dictionnaire d'Eijiro dans Oracle DB part2
[Java] Trouvez le nombre premier avec le tamis Eratostenes (Partie 2)
Jusqu'à ce que vous créiez une application Web avec Servlet / JSP (Partie 1)