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.
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>
Ä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.
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.
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.
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. 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. Sie können sehen, dass das Protokoll im Protokolldatenstrom erstellt wurde. Erweitern Sie es also. Jetzt wissen Sie, dass Sie die Testereignisinformationen erfolgreich erhalten haben.
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.
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.
hochladen.
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. 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.
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.
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.
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