RPAにおけるインテグレーションのためのライブラリ開発
Visual Studioでの開発
Visual Studioを起動し、新規プロジェクト(New Project)より「Visual C#」=>「Window Desktop」=>「Class Library (.NET Framework)」を選択します。名前を「AwsS3Activity」として、「OK」で進みます。
始めにCustom Activityの開発に必要となるライブラリを追加します。「Project」より、「Add Reference...」を選択します。
「Reference Manager」の「Assemblies」にて、System.ActivitiesおよびSystem.ComponentModel.Compositionの参照を検索して選択し、プロジェクトに取り込みます。
続いて、AWSのNuGetパッケージを取り込むため、NuGet Package Managerを開きます。検索窓で、「AWSSDK.S3」を検索します。「AWSSDK.S3」を選択し、「Install」を実行します。依存関係のある「AWSSDK」と「AWSSDK.S3」がインストールされ、プロジェクトから参照可能となります。
「AwsS3Activity.cs」という名称でソースファイルを追加します。まずは、このような形でActivity開発の枠組みだけを作成しておきます。
カスタムアクティビティの作成には、CodeActivityクラスを継承する必要があります。protected override void Execute(CodeActivityContext context)メソッドをオーバーライドしたもので、こちらのメソッドが、UiPathのアクティビティで実行される際に呼ばれるメソッドとなります。
using System; using System.Activities; using System.ComponentModel; namespace UiPathTeam.AwsS3 { public class AwsS3Activity : CodeActivity { protected override void Execute(CodeActivityContext context) { } } }
カスタムアクティビティの開発準備は今しばらく続きます。あらかじめ単体テストの準備をしておきましょう。Visual Studioで別のプロジェクトとして「Add New Project」より、単体テスト用のプロジェクトを作成します。「Visual C#」=>「Test」=>「Unit Test Project (.NET Framework)」を選択し、「UnitTestAwsS3Activity」という名称とします。
この「UnitTestAwsS3Activity」からは、「AwsS3Activity」を参照するため、「Reference Manager」の「Projects」より、「AwsS3Activity」にチェックを入れ、「OK」より参照関係を確立します。
「UnitTest1.cs」という単体テスト用のファイルを作り、「AwsS3Activity」の実装は空っぽですが、ひとまず、単体テストが稼働するか確認しておきます。
それでは、「AwsS3Activity」プロジェクトに戻り、実装を行います。Activityとして受け付ける引数は、下記の通りです。
方向 | パラメータ | 型 | 説明 |
---|---|---|---|
入力 | BucketName | String | S3のバケット名 |
入力 | KeyName | String | アップロード先のキー名称 |
入力 | FilePath | String | アップロード対象のファイルパス |
入力 | AccessKey | String | Accessキー |
入力 | SecretKey | String | Secretキー |
入力 | BucketRegion | String | リージョン情報 |
実装はこのような形になります。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // for custom activity implementation using System.Activities; using System.ComponentModel; // for AWS using Amazon.S3; using Amazon.S3.Transfer; using System.IO; namespace UiPathTeam.AwsS3 { public class AwsS3Activity : CodeActivity { [Category("Input")] [RequiredArgument] public InArgument<string> BucketName { get; set; } [Category("Input")] [RequiredArgument] public InArgument<string> KeyName { get; set; } [Category("Input")] [RequiredArgument] public InArgument<string> FilePath { get; set; } [Category("Input")] [RequiredArgument] public InArgument<string> AccessKey { get; set; } [Category("Input")] [RequiredArgument] public InArgument<string> SecretKey { get; set; } [Category("Input")] [RequiredArgument] public InArgument<Amazon.RegionEndpoint> BucketRegion { get; set; } static string profileName = "default"; private static IAmazonS3 s3Client; private void UploadFile(string bucketName, string keyName, string filePath) { try { var fileTransferUtility = new TransferUtility(s3Client); fileTransferUtility.Upload(filePath, bucketName, keyName); } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); throw e; } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); throw e; } } protected override void Execute(CodeActivityContext context) { var bucketName = BucketName.Get(context); var keyName = KeyName.Get(context); var filePath = FilePath.Get(context); var accessKey = AccessKey.Get(context); var secretKey = SecretKey.Get(context); var bucketRegion = BucketRegion.Get(context); Amazon.Util.ProfileManager.RegisterProfile(profileName, accessKey, secretKey); s3Client = new AmazonS3Client(bucketRegion); UploadFile(bucketName, keyName, filePath); } } }
こちらはカスタムアクティビティとS3へのアップロードに必要なものです。
// for custom activity implementation using System.Activities; using System.ComponentModel; // for AWS using Amazon.S3; using Amazon.S3.Transfer; using System.IO;
UiPathのカスタムアクティビティで引数となるパラメータを、以下のように定義します。
[Category("Input")] [RequiredArgument] public InArgument<string> BucketName { get; set; } [Category("Input")] [RequiredArgument] public InArgument<string> KeyName { get; set; } [Category("Input")] [RequiredArgument] public InArgument<string> FilePath { get; set; } [Category("Input")] [RequiredArgument] public InArgument<string> AccessKey { get; set; } [Category("Input")] [RequiredArgument] public InArgument<string> SecretKey { get; set; } [Category("Input")] [RequiredArgument] public InArgument<Amazon.RegionEndpoint> BucketRegion { get; set; }
S3へファイルをアップロードするメソッドです。事前にインポートしているAWS関連のNuGetにあるUploadメソッドを使用します。
private void UploadFile(string bucketName, string keyName, string filePath) { try { var fileTransferUtility = new TransferUtility(s3Client); fileTransferUtility.Upload(filePath, bucketName, keyName); } catch (AmazonS3Exception e) { Console.WriteLine("Error encountered on server. Message:'{0}' when writing an object", e.Message); throw e; } catch (Exception e) { Console.WriteLine("Unknown encountered on server. Message:'{0}' when writing an object", e.Message); throw e; } }
Executeメソッドは、カスタムアクティビティの実行時に呼ばれるものです。この中で、パラメータの読み取り、S3へのアップロードの処理(前述のUploadFileメソッドの呼び出し)を実装します。今回は出力の引数はありませんが、出力引数がある場合もこのメソッド内で実装しておきます。
protected override void Execute(CodeActivityContext context) { var bucketName = BucketName.Get(context); var keyName = KeyName.Get(context); var filePath = FilePath.Get(context); var accessKey = AccessKey.Get(context); var secretKey = SecretKey.Get(context); var bucketRegion = BucketRegion.Get(context); Amazon.Util.ProfileManager.RegisterProfile(profileName, accessKey, secretKey); s3Client = new AmazonS3Client(bucketRegion); UploadFile(bucketName, keyName, filePath); }
以上で、今回のS3へファイルアップロードするカスタムアクティビティの実装は完了です。
単体テストも1ケースだけですが、下記のテストを実装しておきます。「UnitTestAwsS3Activity」プロジェクトに移動して、「UnitTest1.cs」にテストケースを実装します。「test.txt」というローカルのファイルを、このテストケースを使用してS3の「thinkit-test」バケットへ「custom_activity/uploaded_by_uip.txt」というキー名称でアップロードします。
using Microsoft.VisualStudio.TestTools.UnitTesting; using UiPathTeam.Aws.S3.Activities; using System.Activities; using System.Collections.Generic; namespace UnitTestAwsS3Activity { [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { var activity = new AwsS3Activity(); var input1 = new Dictionary<string, object> { { "BucketName", "thinkit-test" }, { "KeyName", "custom_activity/uploaded_by_uip.txt" }, { "FilePath", @"Z:\workspace\uipath\AwsS3Activity\UnitTestAwsS3Activity\data\test.txt" }, { "AccessKey", "<Input Your AccessKey>" }, { "SecretKey", "<Input Your SecretKey>" }, { "BucketRegion", Amazon.RegionEndpoint.APNortheast1 }, }; var output1 = WorkflowInvoker.Invoke(activity, input1); } } }
きわめてシンプルなテストコードですが、インプットは、Dictionary法で入力引数を渡し、カスタムアクティビティを実行します。今回は特にAssertで単体テストの結果検証をしておりませんが、ここでAssertを行うことでカスタムアクティビティの品質強化ができます。
Visual Studioにて、このテストコードを実行します。このコードが正しく稼働すれば、S3に「test.txt」がアップロードされているはずです。
S3のバケットにアクセスすると、指定したパラメータの通り「thinkit-test」バケットの「custom_activity」フォルダ内に「uploaded_by_uip.txt」というファイル名称でアップロードされていることが確認できます。単体テストとしては、この検証までを一気通貫で実装しておきたいところではありますが、一旦これで良しとしましょう。
動作検証ができましたので、このプロジェクトのビルドを実行してDLLを作成します。「AwsS3Activity」のプロジェクトにて、「Release」を選択し、「Build」を実行します。