Office 365 サイト用 Azure WebJobs の開始
Office 365 で SharePoint Online サービスを実行して利用している場合は、従来のファーム ソリューションでタイマー ジョブにしていた処理の実行方法を考え直す必要があります。
従来の SharePoint 開発では、タイマー ジョブを使用して、スケジュールされたタスクを SharePoint ファームで実行します。 環境で特定のタスクを継続的または繰り返し実行するために一般的に使用される手法は、カスタム タイマー ジョブを開発することです。 Office 365 と SharePoint Online では、従来のタイマー ジョブが存在する通常の場所であるファーム ソリューションを展開する余裕はありません。 その代わりに、タスクをスケジュールする別の方法を見つける必要があります。そこで、Azure WebJobs の出番になります。
この記事では、Office 365 サイトのカスタム ジョブの構築を開始するための基本的な概念と、Office 365 (またはオンプレミス) の SharePoint インストール環境でスケジュールされたジョブとして機能するように Azure WebJob を作成する方法について説明します。
Visual Studio を使用して Web ジョブを作成する
新しい Web ジョブを作成するためにしなければならないのは、新しいコンソール アプリケーションを作成し、必要なアセンブリを確実にプロジェクトに追加するだけです。 この例では、Visual Studio を使用します。
手順 1: コンソール アプリケーションを作成する
最初に、新しいプロジェクトを作成します。その際、必ずコンソール アプリケーション テンプレートを選択してください。 また、必ず .NET Framework 4.5 以降を選択してください。
手順 2:NuGet から SharePoint 固有のアセンブリを追加する
Visual Studio を使用している場合、NuGet パッケージ マネージャー ダイアログ ボックスは以前のバージョンの Visual Studio とは多少異なって表示される可能性がありますが、概念は同じです。
Visual Studio で、[ツール]>[NuGet パッケージ マネージャー]>[ソリューションの Nuget パッケージの管理] に移動し、SharePoint 用アプリを探します。
AppForSharePointOnlineWebToolkit と呼ばれるパッケージをインストールします。
このツールキットは、SharePoint クライアント側オブジェクト モデル (CSOM) を使用するために必要なヘルパー クラスをインストールします。
コンソール アプリケーション プロジェクトに次の 2 つの新しいクラスが表示されていることを確認することにより、NuGet パッケージが機能したことを確かめてください。
- SharePointContext.cs
- TokenHelper.cs
手順 3:Office 365 サイトでジョブを実行するために必要なコードを追加する
この時点で、コンソール アプリケーションは作成済みであり、簡単に SharePoint と通信するために必要なアセンブリも追加済みです。 次の手順は、コンソール アプリケーションを使用して SharePoint 環境でコマンドを実行できるようにこれらのヘルパー クラスを利用することです。
注:
完成後のサンプルでは、アカウントとパスワードのアプローチ (サービス アカウントのようなもの) を使用します。 この記事の続きで、認証オプションについて説明します。
SharePoint Online サイト コレクションの呼び出しを作成する
次のコードは、NuGet パッケージからヘルパー クラスを追加したサイトに呼び出しを関連付ける方法の例を示しています。
static void Main(string[] args)
{
using (ClientContext context = new ClientContext("https://redacted.sharepoint.com"))
{
// Use default authentication mode
context.AuthenticationMode = ClientAuthenticationMode.Default;
// Specify the credentials for the account that will execute the request
context.Credentials = new SharePointOnlineCredentials(GetSPOAccountName(), GetSPOSecureStringPassword());
// TODO: Add your logic here!
}
}
private static SecureString GetSPOSecureStringPassword()
{
try
{
Console.WriteLine(" - > Entered GetSPOSecureStringPassword()");
var secureString = new SecureString();
foreach (char c in ConfigurationManager.AppSettings["SPOPassword"])
{
secureString.AppendChar(c);
}
Console.WriteLine(" - > Constructed the secure password");
return secureString;
}
catch
{
throw;
}
}
private static string GetSPOAccountName()
{
try
{
Console.WriteLine(" - > Entered GetSPOAccountName()");
return ConfigurationManager.AppSettings["SPOAccount"];
}
catch
{
throw;
}
}
ご覧のとおり、サンプル アプリケーションには、app.config ファイルからアカウント名とアカウント パスワードを取得するための 2 つのヘルパー メソッドが追加されています。 これについては、この記事の続きにある認証に関するセクションで説明しています。
Main メソッドに関しては、ポータルに接続するために必要なものはこれで十分です。 コードから SharePoint を操作する方法を詳しく説明する前に、認証用のオプションについて説明します。
認証オプションについて考慮する
認証には 2 つのオプションがあります。 次のセクションでは、一般的に使用される方法と、その違いについて説明します。
オプション 1: サービス アカウント (ユーザー名とパスワード) を使用する
このアプローチはとても単純であり、Office 365 テナントにアカウントとパスワードを入力するだけで、CSOM などを使用してサイトでコードを実行できるようになります。 これは、前述のサンプル コードで実行された方法です。
Office 365 で新しいサービス アカウントを作成する
これを行うには、サービス アカウントとして機能する特定のアカウントを作成する必要があります。これは、特定のアプリケーション用のサービス アカウントか、すべてのジョブとサービスで使用できる汎用的なサービス アプリケーション アカウントになります。
このデモのために、「SP WebJob」という名前の新しいアカウントを作成しました。
ジョブに必要なアクセス許可によっては、アカウントのセットアップ時にそのアクセス許可を編集する必要があります。
app.config に資格情報を保存する
プロジェクトの app.config ファイル内で資格情報を指定すると、コードの実行可能ファイルから容易に取り出すことができるようになります。 app.config は、次のようになっています。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="SPOAccount" value="spwebjob@redacted.onmicrosoft.com"/>
<add key="SPOPassword" value="redacted"/>
</appSettings>
</configuration>
この app.config 内には次の 2 つの設定があります。
- SPOAccount
- SPOPassword
最初のコード スニペットをもう 1 度確認すると、これらの設定は app.config ファイルの設定になっています。 これは、アカウント名とパスワードをクリア テキストとして app.config に保存することを示しているだけです。このアプローチを選択した場合、パスワードを保存して保護する方法と場所については、自身のプロジェクトで決定する必要があります。
指定したアカウントでジョブを実行する
アプリケーションを実行すると、それは SharePointOnlineCredentials() コンストラクターで指定されたアカウントを使用して実行されます。
前のサンプルでは、Web ジョブは、SharePoint Online サイト コレクションでホストされているサイトの 1 つにあるカスタム リストに対してアクションを実行していました。
このため、サービス アカウントによってポータルで実行された変更を容易に追跡することができます。 そのようなわけで、アカウントの名前をわかりやすく付けることは重要です。そうすれば、すべてのユーザーは変更/作成されたメタデータを調べるだけで、変更がサービスによって自動的に行われたことを知ることができます。
オプション 2:アカウント/パスワードの指定を避けるため、OAuth を使用し、リクエストに認証トークンを含める
「SharePoint アドインをタイマー ジョブとして構築する」という題名の Kirk Evans のブログ投稿では、パスワードと資格情報をアプリケーションに保存したくない場合に、アクセス トークンを利用して渡すことによってユーザー名/パスワードのセットアップを避ける方法を説明しています。
CSOM を使用してコードを拡張する
これで、Office 365 サイトに認証して要求を実行できる有効なコンソール アプリケーションができました。 まだ何も実行していないので、「Automatic Translations」という名前のリストから情報を引き出すサンプル スニペットを実行してみましょう。 このコード ロジックでは、翻訳されていないアイテムがリスト内にあるかどうかを判別します。 翻訳サービスの呼び出しを実行し、目的の出力言語にテキストを翻訳します。
static void Main(string[] args)
{
try
{
Console.WriteLine("Initiating Main()");
using (ClientContext context = new ClientContext("https://redacted.sharepoint.com"))
{
Console.WriteLine("New ClientContext('https://redacted.sharepoint.com') opened. ");
context.AuthenticationMode = ClientAuthenticationMode.Default;
context.Credentials = new SharePointOnlineCredentials(GetSPOAccountName(), GetSPOSecureStringPassword());
Console.WriteLine("Authentication Mode and Credentials configured");
List translationlist = context.Web.Lists.GetByTitle("Automatic Translations");
context.Load(translationlist);
context.ExecuteQuery();
Console.WriteLine("TranslationList fetched, loaded and ExecuteQuery'ed");
if (translationlist != null && translationlist.ItemCount > 0)
{
Console.WriteLine("The list exist, let's do some magic");
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml =
@"<View>
<Query>
<Where><Eq><FieldRef Name='IsTranslated' /><Value Type='Boolean'>0</Value></Eq></Where>
</Query>
</View>";
ListItemCollection listItems = translationlist.GetItems(camlQuery);
context.Load(listItems);
context.ExecuteQuery();
Console.WriteLine("Query for listItems executed.");
foreach (ListItem item in listItems)
{
item["Output"] = TranslatorHelper.GetTranslation(item["Title"], item["Target Language"], item["Original Language"]);
item["IsTranslated"] = true;
item.Update();
}
context.ExecuteQuery();
Console.WriteLine("Updated all the list items you found. Carry on...");
}
}
}
catch (Exception ex)
{
Console.WriteLine("ERROR: " + ex.Message);
Console.WriteLine("ERROR: " + ex.Source);
Console.WriteLine("ERROR: " + ex.StackTrace);
Console.WriteLine("ERROR: " + ex.InnerException);
}
}
TranslatorHelper クラスはカスタム翻訳 API を呼び出すヘルパー クラスですが、この記事で扱う範囲ではないため、この投稿では詳細を説明しません。
注:
コードを見ると、これはデモであることがわかります。運用環境で使用されることはありません。 コーディング規則とセキュリティ原則に沿って、変更を加え、調整してください。 ただし、Console.WriteLine のすべての追加部分は、Azure portal からジョブの実行を簡単に確認するために追加されています。 ログと監視の詳細については、この記事の続きで扱います。
Azure への Web ジョブの発行
Web ジョブの開発が完了し、Azure 環境 (Azure Web サイト) に展開する準備が整ったら、次のセクションで説明する 2 種類の主なオプションのいずれかを実行できます。
オプション 1:Web ジョブ バイナリの入った zip ファイルを Azure portal にアップロードする
自身の優位性を Azure 内で維持する場所である Azure portal を使用して、Visual Studio のビルドからの出力が含まれる zip ファイルをアップロードすることができます。 これは、コードをコンパイルして展開の担当者に送る簡単な方法です。
zip ファイルを作成する
Visual Studio ビルドからのすべての出力ファイル (通常は bin/Debug or bin/Release フォルダーにあります) を入手します。
これらのファイルを圧縮すると、Web ジョブに適した zip ファイルが得られます。
ジョブを展開する Web サイトを見つける
パッケージを取得したら、次の手順は Azure portal にアクセスしてサインインします。
そこから、新しい Web サイトを作成するか、既存のサイトを使用する必要があります。 この Web サイトは、ホスト、Web ジョブのホストになります。
Web サイトの設定ウィンドウを下にスクロールすると、[操作] ヘッダーの下に [Web ジョブ] というタイルがあります。
矢印が指している箇所をクリックします。
Web ジョブをアップロードする
[+ 追加] 記号を選択して Web ジョブをアップロードします。
名前とジョブを実行する方法を選択し、実際に zip ファイルをアップロードします。
重要
[実行方法] の選択肢には現時点では [オンデマンド] と [連続] しかありませんが、必要とされている [スケジュール済み] ももうすぐサポートされます。 Azure からの直接発行に関する次のセクションで、Visual Studio 内からスケジュールを設定できます。
これで Web ジョブを Azure portal から実行できるようになりました。
オプション 2:Visual Studio から Azure に直接発行する
Visual Studio 内のツールを使用して、ホストされるサービスに変更を即座に直接発行できます。 Visual Studio のダイアログからジョブの実行方法を直接スケジュールすることもできます。
Visual Studio から Web ジョブを発行する
注:
以前のバージョンの Visual Studio を実行している場合、これらのダイアログは若干異なる可能性があります。 また、この作業を初めて行う場合は、Azure アカウントにサインインするようにサインイン ダイアログが表示される可能性があります。
プロジェクトを右クリックして、[Azure WebJob として発行する] を選択します。
Azure WebJob の追加
これを選択すると、ジョブを構成できる新しいダイアログが表示されます。 定期的にジョブが実行されるようにスケジュールする (毎晩 1 回など) 場合、ダイアログからスケジュールを直接構成できます。
[Web ジョブ名] は Web に適したものにします
[Web ジョブ実行モード] を選択します。 毎日特定の時刻に実行されるようにする場合は、[スケジュールで実行する] を選択します。
ジョブを定期的なジョブにするか、1 回限りのジョブにするかを指定します。 タイマー ジョブをシミュレートするため、ジョブを毎晩実行し、終了日を指定しない場合、定期的なジョブにする必要があります。
必要な場合は、スケジュールを毎分の実行まで細かく設定することができます。
開始する日付と時間、タイム ゾーンを指定します。
[OK] をクリックします。 Visual Studio は、「NuGet パッケージを発行する WebJobs のインストール中」というメッセージを送信します。
実際には、ジョブの構成が含まれる新しいファイル "webjob-publish-settings.json" がプロジェクトに追加されます。
このファイルは次のようになっています。
{ "$schema": "http://schemastore.org/schemas/json/webjob-publish-settings.json", "webJobName": "Zimmergren-O365-WebJobSample", "startTime": "2015-01-09T01:00:00+01:00", "endTime": null, "jobRecurrenceFrequency": "Day", "interval": 1, "runMode": "Scheduled" }
注:
ダイアログを使用してスケジュールを既に設計したので、この時点ではこのファイルは必要ありません。
発行/展開ターゲットを選択する
ダイアログでの次の手順は、Web ジョブを発行/配置する場所の指定です。 既存のサイトを認証して選択するため、発行プロファイルをインポートするか、Azure Web サイトを選択することができます。
Azure portal で [インポート] を選択し、Azure Web サイトからダウンロードした発行プロファイル ファイルを指定します。
発行
これを実行するためにしなければならないのは、[発行] を選択することだけです。 [Web 発行アクティビティ] ダイアログに、Web ジョブ展開の進捗状況が表示されます。
完了すると、Azure portal に Web ジョブが表示されています。
Web ジョブの状態は [完了] として表示されます。 未処理の例外がスローされる場合や異常な動作が発生する可能性がある場合は、失敗/エラーが返されます。
[タイプ] には引き続き [オンデマンド] と表示されていますが、このジョブは実際には 1 時間ごとに実行されます。
ジョブの監視とログの確認
上記のすべての手順を完了すると、ジョブがスケジュールされたタスクとしてクラウドで実行され、Office 365 サイトに対するアクションを実行しています。
ジョブが最後に実行された日時、ジョブの毎回の実行の結果、またはジョブの実行中に何が起こったかを確認するには、Web ジョブの概要で [ログ] の下にあるリンクを選択できます。
このとき、状態/結果を含む、選択したジョブのすべての実行の概要が表示されます。
強調表示されたリンクを選択することにより、特定の実行の詳細を表示し、ジョブのログを見て正常に実行されていることを確認することができます。 これが関係するのは、ジョブによってエラーが発生し、状況を調査する必要がある場合や、ジョブの結果が不正確または予期したものと違う場合です。
また、このデモ用のコンソール アプリケーションで使用した Console.WriteLine ステートメントがジョブ実行ログに表示されることがわかります。
関連項目
- Azure WebJobs に関する元のブログ投稿 (Tobias Zimmergren)
- Visual Studio を使用して Web ジョブを開発し展開する (Azure App Service)
- SharePoint Online とやり取りする単純なリモート タイマー ジョブ ビデオ (Andrew Connell、Channel9)
- Office 365 で Microsoft Azure WebJobs を使用する
- PnP リモート タイマー ジョブ フレームワーク