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 2] 3.5: Java [Fortsetzung] <-Main
Bevor wir die Quelle bis zur letzten Phase bearbeiten, richten wir Lambda ein. Wenn Lambda auf andere Dienste in der VPC zugreifen möchte, wie z. B. EC2 und RDS, muss die von Lambda ausgeführte Funktion selbst ebenfalls zur VPC gehören. Zu diesem Zweck muss die IAM-Rolle usw. festgelegt werden. Wenn diese abgeschlossen ist, muss die Rolle, die den Zugriff auf die VPC ermöglicht, wenn Lambda ein Triggerereignis erkennt, ENI (Elastic Network Interface). Da //docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-eni.html) automatisch zugewiesen wird, können Lambda-Funktionen auf Ressourcen in der VPC zugreifen. Ich werde. (Je mehr Sie wissen, desto besser ist AWS ...)
Hinweis) Die Quellversion sollte mssql-jdbc-7.0.0.jre8.jar sein.
Wählen Sie in der Lambda-Verwaltungskonsole die erstellte lambda_s3_exec_role aus und fügen Sie eine Richtlinie hinzu. Fügen wir eine Richtlinie "AWSLambdaVPCAccessExecutionRole" hinzu, um auf Ressourcen in der VPC zuzugreifen. Wenn das Zugriffsrecht auf CloudWatch-Protokolle angehängt und eingegeben ist, ist die Vorbereitung abgeschlossen.
Öffnen Sie die Lambda-Konsole, stellen Sie die Ausführungsumgebung auf Java8 ein und erstellen Sie eine neue Funktion. Öffnen Sie die Seite mit den Funktionsdetails und setzen Sie die Ausführungsrolle auf lambda_s3_exec_role. Wählen Sie als Nächstes in [Netzwerk] "test_vpc" aus, das in der AWS-Edition erstellt wurde (um genau zu sein, wählen Sie "VPC, zu der die zu aktivierende Ressource gehört" wie EC2 oder RDS). * 1 Dies führt dazu, dass die Lambda-Funktion zur VPC gehört und eine ENI ausgibt. Wählen Sie außerdem das entsprechende Subnetz und die Sicherheitsgruppe aus. Speichern Sie nach Abschluss der Netzwerkeinstellungen die Funktionseinstellungen.
Hier ist ein Teil zu beachten.
Um auf die Ressourcen (EC2, RDS usw.) in der VPC zugreifen zu können, musste die Lambda-Funktion in der VPC wie im vorherigen Ablauf registriert werden. Sobald die Lambda-Funktion jedoch zu einer Ressource innerhalb der VPC wird, kann sie nicht mehr auf Dienste außerhalb der VPC zugreifen (S3, Kinesis usw.).
Weitere Informationen finden Sie im folgenden Artikel. Zugriff auf externe Dienste von Lambda in VPC
Um dies zu vermeiden,
--Erstellen eines NAT-Gateways --Erstellen Sie den Endpunkt
Es gibt, aber diesmal ist es einfach, also möchte ich mit der Einstellung mit letzterem fortfahren.
Wählen Sie in der Navigationsleiste der VPC-Verwaltungskonsole "Endpunkt" aus und klicken Sie auf "Endpunkt erstellen". Dieses Mal ist kein Zugriff auf andere als S3 erforderlich, daher lautet der Status wie folgt. Wählen Sie als Nächstes die VPC aus. Sie können die Routentabelle auswählen, indem Sie die VPC auswählen, zu der die Lambda-Funktion oder die EC2-Instanz gehört. Wenn Sie mehrere Routentabellen haben, wählen Sie die richtige aus.
Zu diesem Zeitpunkt sind die Einstellungen fast abgeschlossen. Das AWS-Konfigurationsdiagramm, in dem die bisher vorgenommenen Änderungen zusammengefasst sind, lautet wie folgt.
1. EC2 gehört zu VPC und befindet sich in einem Subnetz. EIP ist ebenfalls zugewiesen. 2. Lambda gehört zum selben Subnetz wie EC2. 3. Der Endpunkt wird verwendet, um die Kommunikation zwischen Lambda innerhalb der VPC und S3 außerhalb der VPC herzustellen. 4. Der Endpunkt wird in der Routentabelle des Subnetzes festgelegt, zu dem EC2 und Lambda gehören.Lassen Sie uns nun noch einmal bestätigen, dass "die Lambda-Funktion ausgeführt und die entsprechende Datei gelesen werden kann, indem der Upload der CSV-Datei nach S3 ausgelöst wird".
DetectS3Event.java
package lambdaTest.S3toLambda;
/*Import weggelassen*/
public class DetectS3Event implements RequestHandler<S3Event, Object>
{
LambdaLogger lambdaLogger = null;
public AmazonS3 createS3Client() throws Exception
{
AWSCredentials credentials = new BasicAWSCredentials("<accessKey>","<secretKey>");
AmazonS3 client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.build();
return client;
}
@Override
public Context handleRequest(S3Event event, Context context) {
context.getLogger().log("Input: " + event);
lambdaLogger = context.getLogger();
// ===== get event information (S3 Put) =====
S3EventNotificationRecord record = event.getRecords().get(0);
String bucketName = record.getS3().getBucket().getName(); // s3 bucket name
String key = record.getS3().getObject().getKey(); // s3 object key
lambdaLogger.log("bucketName = " + bucketName);
lambdaLogger.log("object key = " + key);
try {
AmazonS3 client = createS3Client();
// Get target object of event
S3Object object = client.getObject(new GetObjectRequest(bucketName, key));
lambdaLogger.log("S3 client = " + client.toString());
BufferedInputStream bis = new BufferedInputStream(object.getObjectContent());
BufferedReader br = new BufferedReader(new InputStreamReader(bis));
String line = "";
// Output contents of object line by line
while((line = br.readLine()) != null) {
lambdaLogger.log(line);
}
} catch (IOException e) {
lambdaLogger.log("IOException error message : " + e.getErrorMessage());
} catch (AmazonServiceException e) {
lambdaLogger.log("AWSException error message : " + e.getErrorMessage());
} catch (Exception e) {
lambdaLogger.log("Exception error message : " + e.getMessage());
}
return null;
}
}
Laden Sie nach dem Erstellen der obigen Datei das mit Maven usw. verpackte Glas auf Lambda hoch.
Laden Sie die folgende CSV in S3 hoch.
emp_values.csv
1001,Dean,28
1002,Sam,25
1003,John,51
1004,Bobby,54
1005,Meg,26
Stellen Sie eine Verbindung zu CloudWatch her und überprüfen Sie das Protokoll. Sie können sehen, dass die obige CSV Zeile für Zeile in das Protokoll ausgegeben wird.
Zuletzt fügen wir diese CSV in die DB auf EC2 ein.
Die Datenbank und die Tabelle sind die vorherigen [Java-Teil [Teil 2]](https://qiita.com/yut0201/items/0d955b37f1f461cce815#%E3%83%87%E3%83%BC%E3%82%BF%E3% 83% 99% E3% 83% BC% E3% 82% B9% E3% 81% 8A% E3% 82% 88% E3% 81% B3% E3% 83% A6% E3% 83% BC% E3% 82% Verwenden Sie die in B6% E3% 81% AE% E4% BD% 9C% E6% 88% 90 erstellte LambdaTestDB-Mitarbeitertabelle.
Stellen Sie sicher, dass die Tabelle keine Datensätze enthält.
1> SELECT * FROM employee;
2> go
emp_id emp_name age
----------- -------------------- -----------
(0 rows affected)
Jetzt bearbeiten wir die Quelle.
DetectS3Event.java
package lambdaTest.S3toLambda;
/*Import weggelassen*/
public class DetectS3Event implements RequestHandler<S3Event, Object>
{
LambdaLogger lambdaLogger = null;
Connection mssqlCon = null;
public AmazonS3 createS3Client() throws Exception
{
AWSCredentials credentials = new BasicAWSCredentials(
"<accessKey>",
"<secretKey>");
AmazonS3 client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.build();
return client;
}
@Override
public Context handleRequest(S3Event event, Context context) {
context.getLogger().log("Input: " + event);
lambdaLogger = context.getLogger();
// ===== get event information (S3 Put) =====
S3EventNotificationRecord record = event.getRecords().get(0);
String bucketName = record.getS3().getBucket().getName(); // s3 bucket name
String key = record.getS3().getObject().getKey(); // s3 object key
lambdaLogger.log("bucketName = " + bucketName);
lambdaLogger.log("object key = " + key);
try {
AmazonS3 client = createS3Client();
S3Object object = client.getObject(new GetObjectRequest(bucketName, key));
lambdaLogger.log("S3 client = " + client.toString());
BufferedInputStream bis = new BufferedInputStream(object.getObjectContent());
BufferedReader br = new BufferedReader(new InputStreamReader(bis));
ResourceBundle sqlServerResource = ResourceBundle.getBundle("sqlServer");
DatabaseInfo sqlServerInfo = new DatabaseInfo(sqlServerResource.getString("driver"),
sqlServerResource.getString("url"),
sqlServerResource.getString("user"),
sqlServerResource.getString("pass"));
/* ======== SQL Server connection ======== */
lambdaLogger.log("SQL Server Session creating...");
SqlServer sqlServer = new SqlServer();
mssqlCon = sqlServer.openConnection(sqlServerInfo);
lambdaLogger.log("SUCCESS : SQL Server session created !!");
String line = "";
Statement insertStmt = mssqlCon.createStatement();
while((line = br.readLine()) != null) {
String[] values = line.split(",");
String insertRecord = "INSERT INTO employee VALUES("
+ values[0] + ", '"
+ values[1] + "', "
+ values[2] + ");";
insertStmt.executeUpdate(insertRecord);
}
if (insertStmt != null) insertStmt.close();
if (mssqlCon != null) sqlServer.closeConnection(mssqlCon);
if (br != null) br.close();
} catch (IOException e) {
e.printStackTrace();
} catch (AmazonServiceException e) {
lambdaLogger.log("Error message : " + e.getErrorMessage());
} catch (Exception e) {
lambdaLogger.log("Exception error message : " + e.getMessage());
}
return null;
}
}
In der while-Anweisung werden CSVs, die zeilenweise gelesen werden, in einem durch Kommas getrennten Array angeordnet und jeweils als Wert jeder Spalte des Datensatzes eingefügt. Sie benötigen eine Verbindung, um eine Verbindung zur Datenbank herzustellen. Erstellen Sie daher unten eine neue Datei.
SqlServer.java
package lambdaTest.db;
/*Import weggelassen*/
public class SqlServer {
public SqlServer() {
super();
}
public Connection openConnection(DatabaseInfo dbInfo)
{
Connection con = null;
try {
Class.forName(dbInfo.getDriver());
con = DriverManager.getConnection(dbInfo.getUrl(), dbInfo.getDbUser(), dbInfo.getDbPass());
} catch (SQLException | ClassNotFoundException e) {
System.out.println("anything Exception : " + e);
}
return con;
}
public void closeConnection(Connection con) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Delegieren Sie die Verbindungsverwaltung an die Datenbank an diese Klasse. Es gibt kein Problem mit der harten Codierung für jeden für die Verbindung erforderlichen Parameter wie Verbindungs-URL, Benutzername, Kennwort usw. Stellen Sie es als Eigenschaftendatei mit Schwerpunkt auf Wiederverwendbarkeit bereit.
sqlServer.properties
driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
url=jdbc:sqlserver://<EC2-privateIP>:<portNo>;databaseName=<databaseName>
user=<userName>
pass=<password>
Da Sie zum Verknüpfen der Eigenschaftendatei eine Klasse benötigen, erstellen wir auch die folgende Klasse.
DatabaseInfo.java
package lambdaTest.S3toLambda;
final public class DatabaseInfo {
String driver;
String url;
String dbUser;
String dbPass;
public String getDriver() {
return driver;
}
public String getUrl() {
return url;
}
public String getDbUser() {
return dbUser;
}
public String getDbPass() {
return dbPass;
}
public DatabaseInfo(String driver, String url, String dbUser, String dbPass) {
this.driver = driver;
this.url = url;
this.dbUser = dbUser;
this.dbPass = dbPass;
}
}
Fügen Sie abschließend ein paar Zeilen zu pom.xml hinzu, damit Maven die externe Eigenschaftendatei korrekt lesen kann. Hier wird nur der hinzuzufügende Build-Abschnitt extrahiert und die hinzugefügte Linie mit einem Stern markiert.
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<encoding>UTF-8</encoding>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<archive>
<manifest>
<mainClass>com.gmail.greencoffeemaker.MainApp</mainClass>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>./src/resources/</Class-Path>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<!--Postscript-Teil-->
<configuration>
<target>
<!--Kopieren: /src/main/resources => /target/resources -->
<mkdir dir="${project.build.directory}/resources" />
<copy todir="${project.build.directory}/resources">
<fileset dir="${project.basedir}/src/main/resources" />
</copy>
</target>
</configuration>
<!--Bisher-->
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Die Bearbeitung ist jetzt abgeschlossen. Laden Sie nach dem Erstellen das Glas auf Lambda hoch und fügen Sie emp_values.csv erneut in S3 ein.
Wenn ich eine Verbindung zu SQL Server auf EC2 herstelle und mir die Tabelle ansehe. .. ..
1> SELECT * FROM employee;
2> go
emp_id emp_name age
----------- -------------------- -----------
1001 Dean 28
1002 Sam 25
1003 John 51
1004 Bobby 54
1005 Meg 26
(5 rows affected)
** Es ist fertig! !! !! ** ** **
Es ist ein paar Jahre her, seit ich Java zum ersten Mal beim Schreiben dieses Artikels berührt habe und AWS ist das erste Ich war in einem zerlumpten Zustand mit fast null Vorbereitung, aber ich war erleichtert, dass ich realisierte, was ich tun wollte. Beim Lesen des Handbuchs, bei der Suche nach Wissen usw. betrug die Arbeitszeit pro Tag weniger als 3 Stunden und das Arbeitsgefühl etwa 2 Wochen. Ich habe das Gefühl, dass der größte Teil der Arbeit darin bestand, Stolperfehler auf dem Weg zu vermeiden.
Ich möchte die Arbeitseffizienz verbessern. Verzweifelt.
Recommended Posts