Bis INSERT S3-Objekt in EC2 DB mit Lambda @ java: Java [Teil 2]

Einführung

Dieser Artikel erinnert daran, was AWS, Java (fast) Anfänger vor dem Einfügen von S3-Objekten in EC2 DB (SQL Server) mit Lambda @ java getan haben. Dies ist die endgültige Ausgabe der ersten Post-Trilogie. Wenn Sie darauf hinweisen, dass dies hier besser ist, bitte! !!

1: AWS Edition 2: Java [Teil 1] 3: Java-Teil [Teil 2] <Hauptteil 3.5: Java Edition [Fortsetzung]

Das letzte Mal habe ich bestätigt, dass ich den Namen der Datei erhalten kann, die ich in den S3-Bucket hochgeladen habe. Senden wir nun den Dateinamen, den Sie zuletzt erhalten haben, per E-Mail.

Dieses Mal habe ich übrigens versucht, das Javax Mail-Paket zu verwenden.

Bearbeiten Sie pom.xml

Fügen Sie den Abhängigkeiten in pom.xml die folgende Beschreibung hinzu.

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

E-Mail senden

Ändern Sie die ListingNames-Methode der ReadS3Object-Klasse wie folgt:

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);

    //Rufen Sie eine Liste der Objekte ab und geben Sie den Objektnamen an die Konsole aus
    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);
}

Ich brauche die Ausgabe nicht an die Konsole, also habe ich sie auskommentiert und stattdessen in einer String-Typ-Liste gespeichert. Da E-Mails von der sendMailTest () -Methode gesendet werden, implementieren wir den Inhalt sofort.

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();

        //Grundinformation. Hier ist ein Beispiel für die Verbindung zu nifty.
        properties.setProperty("mail.smtp.host", "smtp.gmail.com");
        properties.setProperty("mail.smtp.port", "587");
        
        //Timeout-Einstellung
        properties.setProperty("mail.smtp.connectiontimeout", "60000");
        properties.setProperty("mail.smtp.timeout", "60000");

        //Authentifizierung
        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);
          }
	}

Legen Sie alle Quell- und Zieladressen für fromAddr und toAddr fest. Da wir diesmal die Google Mail-Adresse verwenden, haben wir die Google Mail-Adresse für den SMTP-Server festgelegt. Im Inhalt werden die Objektnamen nach der Zeichenfolge verkettet und je nach Anzahl der Objekte durch Kommas getrennt.

Das Zeitlimit für Verbindung und Übertragung beträgt 60.000 Millisekunden. Es kann jedoch ein beliebiger Wert im Bereich von 0 bis 2147483647 eingestellt werden.

Darüber hinaus muss Google Mail eine SMTP-Authentifizierung durchführen, um eine Weiterleitung durch Dritte zu verhindern. Daher werden den Eigenschaften Authentifizierungsinformationen hinzugefügt. Das Argument von PasswordAuthentication () ist die ID (E-Mail-Adresse) und das Kennwort des Google Mail-Kontos.

Packen Sie dann in diesem Zustand erneut mit [Run] -> [S3toLambda] in jar um.

Hinweis) S3 bis Lambda ist die Ausführungskonfiguration, die während des vorherigen Maven-Builds konfiguriert wurde, und das Ziel ist "Paketschatten: Schatten".

Klicken Sie nach dem Hochladen des Glases auf Lambda auf Test. Wenn Sie sich mit der Zieladresse beim Google Mail-Konto anmelden und bestätigen können, dass die E-Mail in Ihrem Posteingang eingegangen ist, sind Sie erfolgreich.

Änderungen der Lambda-Rollenrichtlinie

Bei der Ausführung der Lambda-Funktion möchte ich das normale / abnormale Ende des Ausführungsergebnisses im Protokoll überprüfen können. Geben wir der Lambda-Ausführungsrolle lambda_s3_exec_role Schreibberechtigung für CloudWatch-Protokolle.

Stellen Sie zunächst eine Verbindung zur IAM-Verwaltungskonsole her.

Wählen Sie in der Navigationsleiste auf der linken Seite des Bildschirms Rolle aus und klicken Sie auf die zuvor erstellte lambda_s3_exec_role. Einige Richtlinien werden standardmäßig von AWS bereitgestellt, aber dieses Mal werde ich eine Inline-Richtlinie erstellen (es ist praktisch, sich daran zu erinnern, da sie angepasst werden kann). Klicken Sie rechts auf dem Bildschirm auf "Inline-Richtlinie erstellen", um den folgenden Bildschirm anzuzeigen.

02_create_policy.png

Wählen Sie die Registerkarte JSON und kopieren Sie die folgende Beschreibung.

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

Hinweis) In Bezug auf "Version" scheint die Formatversion auf der AWS-Seite angegeben zu sein. Lassen Sie sie also unverändert, ohne sie zu ändern.

Die obige Beschreibung ist übrigens ein Vollzugriffsstatus, der "Alle Aktionen (Lesen / Schreiben) für alle Ressourcen (Protokollgruppe, Protokolldatenstrom usw.) von CloudWatch-Protokollen zulassen". Wenn Sie die Berechtigungen einschränken möchten, nehmen Sie verschiedene Änderungen vor und probieren Sie sie aus.

Überprüfen Sie das Protokoll

An dieser Stelle schreiben wir den Code, um das Protokoll auszugeben. Erstellen Sie eine neue Klasse unter dem zuletzt erstellten Paket.

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()); 				//Veranstaltungsname
        lambdaLogger.log(record.getS3().getBucket().getName()); //Eimername
        lambdaLogger.log(record.getS3().getObject().getKey()); 	//Objektschlüssel (Objektname)
	
        return null;
    }
}

Erkennen Sie ein Ereignis in S3 und rufen Sie den Ereignisnamen, den Namen des Zielbereichs und den Namen des Zielobjekts ab Lassen Sie es uns als Protokoll von Lambda Logger ausgeben.

Sobald Sie Ihren Mavan in ein Glas gepackt haben, laden Sie ihn auf Lambda hoch. Ändern Sie den Handler entsprechend. Nachdem Sie auf [Speichern] geklickt haben, legen Sie das Testereignis in der Pulldown-Liste links von [Test] fest.

Wählen Sie bei Auswahl von "Neues Testereignis erstellen" die Option "S3 Put" oder "S3 Delete" aus der Ereignisvorlage aus. Speichern Sie es mit einem beliebigen Namen für Testereignisse. 03_S3_testEvent.png Führen Sie in diesem Zustand [Test] aus, um zu bestätigen, dass das Ausführungsergebnis erfolgreich ist, und sehen Sie sich dann das Protokoll an. 04_lambda_result.png 05_cloudwatch_logs_01.png Sie können sehen, dass das Protokoll im Protokolldatenstrom erstellt wurde. Erweitern Sie es also. 06_cloudwatch_logs_02.png Jetzt wissen Sie, dass Sie die Testereignisinformationen erfolgreich erhalten haben.

Ereignisauslösereinstellungen

Da ich die Ausgabe von Informationen zu den Testdaten im Protokoll bestätigen konnte, habe ich tatsächlich das Ereignis "Datei hochladen" ausgelöst. Lassen Sie uns das Protokoll in CloudWatch ausgeben.

Legen Sie diesmal das Ereignis über die S3-Verwaltungskonsole fest (eine Einstellung von der Lambda-Seite ist ebenfalls möglich).

Wählen Sie den gewünschten Bucket aus und klicken Sie auf die Registerkarte Eigenschaften. Stellen Sie sicher, dass im Block [Ereignisse] keine Ereignisse registriert sind, und erstellen Sie mit [+ Benachrichtigung hinzufügen] das folgende Ereignis. 07_S3_create_event.png

Überprüfen Sie das Ereignisprotokoll

In diesem Artikel

Bearbeiten Sie nach dem Festlegen des Ereignisses die handleRequest (S3Event-Ereignis, Kontextkontext).

DetectS3Event.java


package S3test.S3toLambda;

//Import weggelassen

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); //Konvertieren Sie Zeilen in ein durch Kommas getrenntes Array

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

Als Test mit dem in den oben genannten Quellzustand verpackten Glas, das auf Lambda hochgeladen wurde, Laden Sie die im Voraus vorbereitete CSV wie unten gezeigt hoch. 08_create_csv.png

hochladen. 09_csv_upload.png

Dann, mit diesem Upload als Auslöser, -S3 tritt Lambda-Funktion auf-> Lambda-Funktion schreibt Ausführungsergebnis entsprechend der Ausführungsrolle in CloudWatch-Protokolle Wurde geboren.

Es scheint eine Zeitverzögerung von bis zu einigen Minuten zu geben, bis alle Protokolle ausgegeben werden (ich habe es diesmal nicht genau überprüft), aber schauen wir uns die CloudWatch-Protokolle an. 10_logs.png Ich fand heraus, dass die hochgeladene CSV Zeile für Zeile, durch Kommas getrennt, zwischen der 6. und 23. Zeile des Protokolls ausgegeben wurde.

Versuchen Sie abschließend erneut, die obige CSV zu verwenden, um sie in die Datenbank (SQL Server) auf EC2 einzufügen.

Datenbanken und Benutzer erstellen

Hinweis) Es wird davon ausgegangen, dass SQL Server Express Edition installiert ist. Sie können es unter Official installieren.

Stellen Sie zunächst mit dem folgenden Befehl eine Verbindung zur erstellten EC2-Instanz her.

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

Das Schlüsselpaar, das gleichzeitig mit der EC2-Instanz verwendet wird, wird erstellt. Wenn Sie ein vorhandenes Schlüsselpaar verwenden, ist dies in Ordnung. Die IP-Adresse ist die der EC2-Instanz zugewiesene elastische IP. Sie können den Verbindungsbefehl selbst mit der Schaltfläche [Verbinden] auf der EC2-Verwaltungskonsole überprüfen.

Stellen Sie nach dem Herstellen einer Verbindung zur Instanz eine Verbindung zu SQL Server her.

sqlcmd -S localhost -U SA

Wenn sich die Eingabeaufforderung in 1> ändert, ist die Anmeldung erfolgreich. Als Nächstes erstellen wir eine Datenbank, administrative Benutzer und Tabellen.

Datenbank erstellen

Führen Sie den folgenden Befehl aus. Dieses Mal verwende ich 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

Stellen Sie sicher, dass die Datenbank normal erstellt wurde.

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)

Erstellen Sie als Nächstes eine Tabelle in der erstellten LambdaTestDB.

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

Hinweis) Wenn ein Fehler angezeigt wird, beheben Sie ihn entsprechend.

Bestätigen Sie, dass die Tabelle erfolgreich erstellt wurde.

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)

Wenn das obige Ergebnis erhalten wird, ist die Tabellenerstellung erfolgreich.

Nachdem die einzufügende Tabelle erstellt wurde, bearbeiten Sie auch die Quelle erneut.

Zusammenfassung! ??

Dieser Artikel wurde als drittes Werk aus drei Teilen geschrieben, aber am Anfang war der Band des dritten Werks schwierig, weil ich nicht besonders über die Komposition nachdachte. .. .. (Entschuldigung) Deshalb werde ich die Fortsetzung später als 3.5. Werk veröffentlichen.

Vielen Dank.

Recommended Posts

Bis INSERT S3-Objekt in EC2 DB mit Lambda @ java: Java [Teil 2]
Bis das S3-Objekt mit Lambda @ java in Java eingefügt wird: Java [Teil 1]
Bis INSERT S3 Objekt in EC2 DB mit Lambda @ java: AWS
Bis INSERT S3-Objekt in EC2 DB mit Lambda @ java: Java [Fortsetzung]
AWS Lambda (Lambda) Teil 1 mit Java startet jetzt
[Java] Batch Insert Inserts werden beim Umgang mit MySQL DB in Doma zu einem zusammengefasst.
Einfügen von Eijiros Wörterbuchdaten in Oracle DB Teil2
[Java] Finde die Primzahl mit dem Eratostenes-Sieb (Teil 2)
Bis Sie eine Webanwendung mit Servlet / JSP erstellen (Teil 1)