Skip to content

Commit 947d81b

Browse files
committedDec 3, 2020
Initial_Commit
0 parents  commit 947d81b

17 files changed

+710
-0
lines changed
 

‎.vs/Assignment4AWSLambda/v16/.suo

20 KB
Binary file not shown.

‎Assignment4AWSLambda.csproj

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>netcoreapp3.1</TargetFramework>
4+
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
5+
<AWSProjectType>Lambda</AWSProjectType>
6+
7+
<!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. -->
8+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
9+
</PropertyGroup>
10+
<ItemGroup>
11+
<PackageReference Include="AWSSDK.S3" Version="3.5.5.2" />
12+
<PackageReference Include="AWSSDK.Rekognition" Version="3.5.2.15" />
13+
<PackageReference Include="Amazon.Lambda.Core" Version="1.2.0" />
14+
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.1.0" />
15+
<PackageReference Include="Amazon.Lambda.S3Events" Version="1.2.0" />
16+
</ItemGroup>
17+
</Project>

‎Assignment4AWSLambda.sln

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.30523.141
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Assignment4AWSLambda", "Assignment4AWSLambda.csproj", "{A771ACF5-BF57-4B5C-82FB-2E1FF7337A36}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{A771ACF5-BF57-4B5C-82FB-2E1FF7337A36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{A771ACF5-BF57-4B5C-82FB-2E1FF7337A36}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{A771ACF5-BF57-4B5C-82FB-2E1FF7337A36}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{A771ACF5-BF57-4B5C-82FB-2E1FF7337A36}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {89C7C1D2-4512-418B-91D3-264FB0746553}
24+
EndGlobalSection
25+
EndGlobal

‎Function.cs

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
7+
using Amazon.Lambda.Core;
8+
using Amazon.Lambda.S3Events;
9+
10+
11+
using Amazon.Rekognition;
12+
using Amazon.Rekognition.Model;
13+
14+
using Amazon.S3;
15+
using Amazon.S3.Model;
16+
17+
//test
18+
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
19+
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
20+
21+
namespace Assignment4AWSLambda
22+
{
23+
public class Function
24+
{
25+
/// <summary>
26+
/// The default minimum confidence used for detecting labels.
27+
/// </summary>
28+
public const float DEFAULT_MIN_CONFIDENCE = 70f;
29+
30+
/// <summary>
31+
/// The name of the environment variable to set which will override the default minimum confidence level.
32+
/// </summary>
33+
public const string MIN_CONFIDENCE_ENVIRONMENT_VARIABLE_NAME = "MinConfidence";
34+
35+
IAmazonS3 S3Client { get; }
36+
37+
IAmazonRekognition RekognitionClient { get; }
38+
39+
float MinConfidence { get; set; } = DEFAULT_MIN_CONFIDENCE;
40+
41+
HashSet<string> SupportedImageTypes { get; } = new HashSet<string> { ".png", ".jpg", ".jpeg" };
42+
43+
/// <summary>
44+
/// Default constructor used by AWS Lambda to construct the function. Credentials and Region information will
45+
/// be set by the running Lambda environment.
46+
///
47+
/// This constuctor will also search for the environment variable overriding the default minimum confidence level
48+
/// for label detection.
49+
/// </summary>
50+
public Function()
51+
{
52+
this.S3Client = new AmazonS3Client();
53+
this.RekognitionClient = new AmazonRekognitionClient();
54+
55+
var environmentMinConfidence = System.Environment.GetEnvironmentVariable(MIN_CONFIDENCE_ENVIRONMENT_VARIABLE_NAME);
56+
if(!string.IsNullOrWhiteSpace(environmentMinConfidence))
57+
{
58+
float value;
59+
if(float.TryParse(environmentMinConfidence, out value))
60+
{
61+
this.MinConfidence = value;
62+
Console.WriteLine($"Setting minimum confidence to {this.MinConfidence}");
63+
}
64+
else
65+
{
66+
Console.WriteLine($"Failed to parse value {environmentMinConfidence} for minimum confidence. Reverting back to default of {this.MinConfidence}");
67+
}
68+
}
69+
else
70+
{
71+
Console.WriteLine($"Using default minimum confidence of {this.MinConfidence}");
72+
}
73+
}
74+
75+
/// <summary>
76+
/// Constructor used for testing which will pass in the already configured service clients.
77+
/// </summary>
78+
/// <param name="s3Client"></param>
79+
/// <param name="rekognitionClient"></param>
80+
/// <param name="minConfidence"></param>
81+
public Function(IAmazonS3 s3Client, IAmazonRekognition rekognitionClient, float minConfidence)
82+
{
83+
this.S3Client = s3Client;
84+
this.RekognitionClient = rekognitionClient;
85+
this.MinConfidence = minConfidence;
86+
}
87+
88+
/// <summary>
89+
/// A function for responding to S3 create events. It will determine if the object is an image and use Amazon Rekognition
90+
/// to detect labels and add the labels as tags on the S3 object.
91+
/// </summary>
92+
/// <param name="input"></param>
93+
/// <param name="context"></param>
94+
/// <returns></returns>
95+
public async Task FunctionHandler(S3Event input, ILambdaContext context)
96+
{
97+
foreach(var record in input.Records)
98+
{
99+
if(!SupportedImageTypes.Contains(Path.GetExtension(record.S3.Object.Key)))
100+
{
101+
Console.WriteLine($"Object {record.S3.Bucket.Name}:{record.S3.Object.Key} is not a supported image type");
102+
continue;
103+
}
104+
105+
Console.WriteLine($"Looking for labels in image {record.S3.Bucket.Name}:{record.S3.Object.Key}");
106+
var detectResponses = await this.RekognitionClient.DetectLabelsAsync(new DetectLabelsRequest
107+
{
108+
MinConfidence = MinConfidence,
109+
Image = new Image
110+
{
111+
S3Object = new Amazon.Rekognition.Model.S3Object
112+
{
113+
Bucket = record.S3.Bucket.Name,
114+
Name = record.S3.Object.Key
115+
}
116+
}
117+
});
118+
119+
var tags = new List<Tag>();
120+
foreach(var label in detectResponses.Labels)
121+
{
122+
if(tags.Count < 10)
123+
{
124+
Console.WriteLine($"\tFound Label {label.Name} with confidence {label.Confidence}");
125+
tags.Add(new Tag { Key = label.Name, Value = label.Confidence.ToString() });
126+
}
127+
else
128+
{
129+
Console.WriteLine($"\tSkipped label {label.Name} with confidence {label.Confidence} because the maximum number of tags has been reached");
130+
}
131+
}
132+
133+
await this.S3Client.PutObjectTaggingAsync(new PutObjectTaggingRequest
134+
{
135+
BucketName = record.S3.Bucket.Name,
136+
Key = record.S3.Object.Key,
137+
Tagging = new Tagging
138+
{
139+
TagSet = tags
140+
}
141+
});
142+
}
143+
return;
144+
}
145+
}
146+
}

‎Properties/launchSettings.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"profiles": {
3+
"Mock Lambda Test Tool": {
4+
"commandName": "Executable",
5+
"commandLineArgs": "--port 5050",
6+
"workingDirectory": ".\\bin\\$(Configuration)\\netcoreapp3.1",
7+
"executablePath": "%USERPROFILE%\\.dotnet\\tools\\dotnet-lambda-test-tool-3.1.exe"
8+
}
9+
}
10+
}

‎Readme.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# AWS Lambda S3 and Image Rekognition Function Project
2+
3+
This starter project consists of:
4+
* Function.cs - class file containing a class with a single function handler method
5+
* aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS
6+
7+
You may also have a test project depending on the options selected.
8+
9+
The generated function handler responds to S3 events on an Amazon S3 bucket and if the object is a png or jpg file uses
10+
Amazon Rekognition to detect labels. Once the labels are found it adds them as tags to the S3 Object.
11+
12+
## Here are some steps to follow from Visual Studio:
13+
14+
To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*.
15+
16+
To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree.
17+
18+
To perform testing against your deployed function use the Test Invoke tab in the opened Function View window.
19+
20+
To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window.
21+
22+
To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window.
23+
24+
To view execution logs of invocations of your function use the Logs tab in the opened Function View window.
25+
26+
## Here are some steps to follow to get started from the command line:
27+
28+
Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line.
29+
30+
Install Amazon.Lambda.Tools Global Tools if not already installed.
31+
```
32+
dotnet tool install -g Amazon.Lambda.Tools
33+
```
34+
35+
If already installed check if new version is available.
36+
```
37+
dotnet tool update -g Amazon.Lambda.Tools
38+
```
39+
40+
Execute unit tests
41+
```
42+
cd "Assignment4AWSLambda/test/Assignment4AWSLambda.Tests"
43+
dotnet test
44+
```
45+
46+
Deploy function to AWS Lambda
47+
```
48+
cd "Assignment4AWSLambda/src/Assignment4AWSLambda"
49+
dotnet lambda deploy-function
50+
```

‎aws-lambda-tools-defaults.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"Information": [
3+
"This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
4+
"To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
5+
"dotnet lambda help",
6+
"All the command line options for the Lambda command can be specified in this file."
7+
],
8+
"profile": "default",
9+
"region": "ca-central-1",
10+
"configuration": "Release",
11+
"framework": "netcoreapp3.1",
12+
"function-runtime": "dotnetcore3.1",
13+
"function-memory-size": 256,
14+
"function-timeout": 30,
15+
"function-handler": "Assignment4AWSLambda::Assignment4AWSLambda.Function::FunctionHandler"
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"format": 1,
3+
"restore": {
4+
"C:\\Comp306_AWSAmazon\\Lab4\\Assignment4AWSLambda\\Assignment4AWSLambda.csproj": {}
5+
},
6+
"projects": {
7+
"C:\\Comp306_AWSAmazon\\Lab4\\Assignment4AWSLambda\\Assignment4AWSLambda.csproj": {
8+
"version": "1.0.0",
9+
"restore": {
10+
"projectUniqueName": "C:\\Comp306_AWSAmazon\\Lab4\\Assignment4AWSLambda\\Assignment4AWSLambda.csproj",
11+
"projectName": "Assignment4AWSLambda",
12+
"projectPath": "C:\\Comp306_AWSAmazon\\Lab4\\Assignment4AWSLambda\\Assignment4AWSLambda.csproj",
13+
"packagesPath": "C:\\Users\\sergi\\.nuget\\packages\\",
14+
"outputPath": "C:\\Comp306_AWSAmazon\\Lab4\\Assignment4AWSLambda\\obj\\",
15+
"projectStyle": "PackageReference",
16+
"configFilePaths": [
17+
"C:\\Users\\sergi\\AppData\\Roaming\\NuGet\\NuGet.Config",
18+
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
19+
],
20+
"originalTargetFrameworks": [
21+
"netcoreapp3.1"
22+
],
23+
"sources": {
24+
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
25+
"https://api.nuget.org/v3/index.json": {}
26+
},
27+
"frameworks": {
28+
"netcoreapp3.1": {
29+
"projectReferences": {}
30+
}
31+
},
32+
"warningProperties": {
33+
"warnAsError": [
34+
"NU1605"
35+
]
36+
}
37+
},
38+
"frameworks": {
39+
"netcoreapp3.1": {
40+
"dependencies": {
41+
"AWSSDK.Rekognition": {
42+
"target": "Package",
43+
"version": "[3.5.2.15, )"
44+
},
45+
"AWSSDK.S3": {
46+
"target": "Package",
47+
"version": "[3.5.5.2, )"
48+
},
49+
"Amazon.Lambda.Core": {
50+
"target": "Package",
51+
"version": "[1.2.0, )"
52+
},
53+
"Amazon.Lambda.S3Events": {
54+
"target": "Package",
55+
"version": "[1.2.0, )"
56+
},
57+
"Amazon.Lambda.Serialization.SystemTextJson": {
58+
"target": "Package",
59+
"version": "[2.1.0, )"
60+
}
61+
},
62+
"imports": [
63+
"net461",
64+
"net462",
65+
"net47",
66+
"net471",
67+
"net472",
68+
"net48"
69+
],
70+
"assetTargetFallback": true,
71+
"warn": true,
72+
"frameworkReferences": {
73+
"Microsoft.NETCore.App": {
74+
"privateAssets": "all"
75+
}
76+
},
77+
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\3.1.402\\RuntimeIdentifierGraph.json"
78+
}
79+
}
80+
}
81+
}
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="utf-8" standalone="no"?>
2+
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
4+
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
5+
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
6+
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
7+
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
8+
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\sergi\.nuget\packages\</NuGetPackageFolders>
9+
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
10+
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">5.7.0</NuGetToolVersion>
11+
</PropertyGroup>
12+
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
13+
<SourceRoot Include="$([MSBuild]::EnsureTrailingSlash($(NuGetPackageFolders)))" />
14+
</ItemGroup>
15+
<PropertyGroup>
16+
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
17+
</PropertyGroup>
18+
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
19+
<PkgAWSSDK_Core Condition=" '$(PkgAWSSDK_Core)' == '' ">C:\Users\sergi\.nuget\packages\awssdk.core\3.5.1.42</PkgAWSSDK_Core>
20+
<PkgAWSSDK_S3 Condition=" '$(PkgAWSSDK_S3)' == '' ">C:\Users\sergi\.nuget\packages\awssdk.s3\3.5.5.2</PkgAWSSDK_S3>
21+
<PkgAWSSDK_Rekognition Condition=" '$(PkgAWSSDK_Rekognition)' == '' ">C:\Users\sergi\.nuget\packages\awssdk.rekognition\3.5.2.15</PkgAWSSDK_Rekognition>
22+
</PropertyGroup>
23+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" standalone="no"?>
2+
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
5+
</PropertyGroup>
6+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// <autogenerated />
2+
using System;
3+
using System.Reflection;
4+
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v3.1", FrameworkDisplayName = "")]

0 commit comments

Comments
 (0)
Please sign in to comment.