[JAVA] Erstellen Sie einfach ein virtuelles S3 und testen Sie die Integration zwischen AWS Lambda und S3-Diensten in einer lokalen Umgebung

Vorbereitungen

Bitte installieren Sie das AWS Toolkit für Eclise, bevor Sie es ausführen. Informationen zum Installationsverfahren finden Sie unter dem folgenden Link.

-> Installationsverfahren für das AWS Toolkit

Nach Abschluss der Installation sollte das AWS-Projekt auf dem neuen Projektbildschirm angezeigt werden.

Maven ist eine Voraussetzung, die installiert wurde.

Screenshot from 2017-04-20 17-13-55.png

Schreiben Sie eine Lambda-Funktion

  1. Erstellen Sie zunächst ein Projekt für AWS Lambda Java-Funktionen.

Screenshot from 2017-04-20 17-19-41.png -Projektname: S3EventTutorial -Paketname: com.amazonaws.lambda.s3tutorial Lassen Sie uns die wesentlichen Informationen wie oben behalten. Wenn Sie auf "Fertig stellen" klicken, wird das Projekt erstellt und der allgemeine Projektordner sieht wie folgt aus. Screenshot from 2017-04-20 17-25-12.png

  1. Installieren Sie eine Bibliothek mit dem Namen "s3mock_2.11" in Maven, um S3 zu verspotten. Sie müssen lediglich die abhängigen Bibliotheken in der POM-Datei definieren. Lesen Sie daher die POM-Datei unten und erstellen Sie einen POM für Ihr eigenes Projekt.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.amazonaws.lambda</groupId>
	<artifactId>s3tutorial</artifactId>
	<version>4.0.0</version>
	<dependencies>
		<dependency>
			<groupId>com.amazonaws</groupId>
			<artifactId>aws-lambda-java-core</artifactId>
			<version>1.1.0</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>com.amazonaws</groupId>
			<artifactId>aws-lambda-java-events</artifactId>
			<version>1.3.0</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>com.amazonaws</groupId>
			<artifactId>aws-java-sdk</artifactId>
			<version>1.11.119</version>
			<scope>compile</scope>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.typesafe.akka/akka-http-experimental_2.11 -->
		<dependency>
			<groupId>com.typesafe.akka</groupId>
			<artifactId>akka-http-experimental_2.11</artifactId>
			<version>2.4.11.1</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/com.typesafe.scala-logging/scala-logging_2.11 -->
		<dependency>
			<groupId>com.typesafe.scala-logging</groupId>
			<artifactId>scala-logging_2.11</artifactId>
			<version>3.5.0</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/io.findify/s3mock_2.11 -->
		<dependency>
			<groupId>io.findify</groupId>
			<artifactId>s3mock_2.11</artifactId>
			<version>0.1.10</version>
			<scope>test</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>2.7.22</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.github.tomakehurst/wiremock -->
		<dependency>
			<groupId>com.github.tomakehurst</groupId>
			<artifactId>wiremock</artifactId>
			<version>2.6.0</version>
		</dependency>


	</dependencies>
</project>

Möglicherweise gibt es abhängige Bibliotheken, die sich nicht im Maven-Repository im lokalen Verzeichnis befinden. Führen Sie daher "mvn package" als Befehlszeile im Stammordner des Projekts aus. Und maven lädt die in pom definierte Abhängigkeit herunter.

  1. Lambda-Funktionslogik Öffnen wir die erstellte LambdaFunctionHandler.java und schreiben die Logik. Die Idee ist sehr einfach.

Wenn Sie ein Ereignis erhalten, bei dem eine Datei von S3 hochgeladen wurde, können Sie den Inhalt des Ereignisses anzeigen, die hochgeladene Datei abrufen und auf der Konsole ausschreiben. Sie müssen es nicht erklären, da Sie es sofort sehen können, indem Sie sich den Code ansehen.


public class LambdaFunctionHandler implements RequestHandler<S3Event, Object> {
	
	private AmazonS3 s3Client;
	
	public LambdaFunctionHandler(AmazonS3 s3Client){
		this.s3Client = s3Client;
	}
	public LambdaFunctionHandler(){
		this.s3Client =  new AmazonS3Client(new ProfileCredentialsProvider());
	}
	
	private static void storeObject(InputStream input) throws IOException {
		// Read one text line at a time and display.
		BufferedReader reader = new BufferedReader(new InputStreamReader(input));
		while (true) {
			String line = reader.readLine();
			if (line == null)
				break;
			System.out.println("    " + line);
		}
		System.out.println();
	}

	@Override
	public Object handleRequest(S3Event input, Context context) {
		context.getLogger().log("Input: " + input);

		// Simply return the name of the bucket in request
		LambdaLogger lambdaLogger = context.getLogger();
		S3EventNotificationRecord record = input.getRecords().get(0);
		lambdaLogger.log(record.getEventName()); //Veranstaltungsname

		String bucketName = record.getS3().getBucket().getName();
		String key = record.getS3().getObject().getKey();
		/*
		 * Get file to do further operation
		 */
		try {
			lambdaLogger.log("Downloading an object");

			S3Object s3object = s3Client.getObject(new GetObjectRequest(bucketName, key));

			lambdaLogger.log("Content-Type: " + s3object.getObjectMetadata().getContentType());

			storeObject(s3object.getObjectContent());

			// Get a range of bytes from an object.

			GetObjectRequest rangeObjectRequest = new GetObjectRequest(bucketName, key);
			rangeObjectRequest.setRange(0, 10);
			S3Object objectPortion = s3Client.getObject(rangeObjectRequest);

			System.out.println("Printing bytes retrieved.");
			storeObject(objectPortion.getObjectContent());

		} catch (AmazonServiceException ase) {
			System.out.println("Caught an AmazonServiceException, which" + " means your request made it "
					+ "to Amazon S3, but was rejected with an error response" + " for some reason.");
			System.out.println("Error Message:    " + ase.getMessage());
			System.out.println("HTTP Status Code: " + ase.getStatusCode());
			System.out.println("AWS Error Code:   " + ase.getErrorCode());
			System.out.println("Error Type:       " + ase.getErrorType());
			System.out.println("Request ID:       " + ase.getRequestId());
		} catch (AmazonClientException ace) {
			System.out.println("Caught an AmazonClientException, which means" + " the client encountered "
					+ "an internal error while trying to " + "communicate with S3, "
					+ "such as not being able to access the network.");
			System.out.println("Error Message: " + ace.getMessage());
		}catch (IOException ioe){
			System.out.println("Caught an IOException, which means" + " the client encountered "
					+ "an internal error while trying to " + "save S3 object, "
					+ "such as not being able to access the network.");
			System.out.println("Error Message: " + ioe.getMessage());
		}
		return record.getS3().getObject().getKey();
	}

}


Erstellen wir einen Testfall für den Code, den wir geschrieben haben

Dieses Mal konzentrieren wir uns auf den implementierten Lambda-Code. Öffnen Sie also LambdaFunctionHandlerTest und erstellen Sie einen Testfall. Lesen wir zunächst den Code des Testfalls.


    private static S3Event input;
    private static AmazonS3Client client;

    @BeforeClass
    public static void createInput() throws IOException {
        input = TestUtils.parse("s3-event.put.json", S3Event.class);
        
        S3Mock api = S3Mock.create(8999, "/tmp/s3");
        api.start();
                
        client = new AmazonS3Client(new AnonymousAWSCredentials());
        client.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1));

        // use IP endpoint to override DNS-based bucket addressing
        client.setEndpoint("http://127.0.0.1:8999");

    }

    private Context createContext() {
        TestContext ctx = new TestContext();

        // TODO: customize your context here if needed.
        ctx.setFunctionName("Your Function Name");

        return ctx;
    }

    @Test
    public void testLambdaFunctionHandlerShouldReturnObjectKey() {
    	
        client.createBucket(new CreateBucketRequest("newbucket", "ap-northeast-1"));
    	ClassLoader classLoader = this.getClass().getClassLoader();
    	File file = new File(classLoader.getResource("file/test.xml").getFile());
        client.putObject(new PutObjectRequest(
        		                 "newbucket", "file/name", file));
    	
        LambdaFunctionHandler handler = new LambdaFunctionHandler(client);
        Context ctx = createContext();

        Object output = handler.handleRequest(input, ctx);

        if (output != null) {
        	assertEquals("file/name", output.toString());
            System.out.println(output.toString());
        }
    }

Erstellen und starten Sie zu Testzwecken eine Instanz von S3Mock mit der Funktion createInput. Diese Instanz kauft Port 8999 in Ihrer lokalen Umgebung und wartet auf Ihre Anfrage. Erstellen Sie einen Ordner mit dem Namen "/ temp / s3" und ahmen Sie den Speicher des S3-Dienstes nach.

Das Wichtigste ist der Inhalt der Funktion testLambdaFunctionHandlerShouldReturnObjectKey. Wie Sie sehen können, werden die folgenden Aufgaben implementiert: --Erstellen Sie einen "Test-Bucket". Hinweis: Es ist obligatorisch, die Region anzugeben (wenn Sie sich nicht für den Inhalt der Region interessieren, java.lang.NoSuchMethodError: com.amazonaws.regions.RegionUtils.getRegionByEndpoint (Ljava / lang / String;) Lcom / amazonaws / Ich erhalte einen Fehler namens "Regions / Region" (ein AWS-Fehler). --Laden Sie die im Ressourcenordner unter dem Projekt erstellte Datei / test.xml in den temporären Speicher

Da der Auslöser der Inhalt des in "s3-event.put.json" definierten Ereignisses ist, müssen die Informationen der hochgeladenen Datei im Inhalt von "s3-event.put.json" wiedergegeben werden.


{
  "Records": [
    {
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "us-east-1",
      "eventTime": "1970-01-01T00:00:00.000Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "EXAMPLE"
      },
      "requestParameters": {
        "sourceIPAddress": "127.0.0.1"
      },
      "responseElements": {
        "x-amz-request-id": "",
        "x-amz-id-2": "FMyUVURIY8//JRWeUWerMUE5JgHvANOjpD"
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "testbucket",
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::mybucket"
        },
        "object": {
          "key": "file/name",
          "size": 1024,
          "eTag": "d41d8cd98f00b204e9800998ecf8427e"
        }
      }
    }
  ]
}

Hinweis: Der Bucket-Name und der Objektschlüssel sind am wichtigsten. Wie Sie sehen können, wurde die Datei mit der Schlüsseldatei / dem Schlüsselnamen auf testbuck hochgeladen, sodass der Inhalt von json entsprechend ausgedrückt wird.

#das Ende

Ich habe es im Entwurf erklärt, aber wenn Sie Fragen haben, kontaktieren Sie uns bitte.

Recommended Posts

Erstellen Sie einfach ein virtuelles S3 und testen Sie die Integration zwischen AWS Lambda und S3-Diensten in einer lokalen Umgebung
Untersuchen Sie die Systeminformationen der AWS Lambda-Betriebsumgebung in Java
So erstellen Sie Ihre eigene Anmerkung in Java und erhalten den Wert
Organisieren Sie den Unterschied im Schreibkomfort zwischen dem Java-Lambda-Ausdruck und dem Kotlin-Lambda-Ausdruck.