かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Microsoft Azure ServiceFabricで複数のサービスで設定値を共通化したい

同じDBに繋ぐときとか一か所で設定を終えたいですよね。 ということで手順を備忘録的に残しておこうと思います。基本的には以下に書いてあることです。

Service Fabric での複数の環境の管理 | Microsoft Docs

Step1

サービスのプロジェクト/PackageRoot/COnfig/Settings.xmlに設定値を書く。これは設定を共通化したいプロジェクトが2個あったら2個ともにやります。

<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <!-- これは StateManager のレプリケーターにより使用されます。-->
  <Section Name="ReplicatorConfig">
    <Parameter Name="ReplicatorEndpoint" Value="ReplicatorEndpoint" />
  </Section>
  <!-- これは StateManager のレプリケーション トラフィックをセキュリティで保護するために使用されます。-->
  <Section Name="ReplicatorSecurityConfig" />

  <!-- ここで、カスタム構成セクションとパラメーターを追加します。-->
  <!--
  <Section Name="MyConfigSection">
    <Parameter Name="MyParameter" Value="Value1" />
  </Section>
  -->

  <!-- これを追加 -->
  <Section Name="UserDatabase">
    <Parameter Name="ConnectionString" Value="" />
  </Section>
</Settings>

Valueにはなんか書いてもかまいませんが、どうせ後で上書きされるので適当な値を突っ込んでおきましょう。

Step2

アプリケーションのプロジェクトのApplicationPackageRoot/ApplicationManifest.xmlのServiceManifestImportのConfigOverridesで先ほどの設定をオーバーライドする定義を追加します。これも2サービスあったら2つぶんやります。

Valueのところでかっこで囲っているのがパラメータ名になります。

<ServiceManifestImport>
  <ServiceManifestRef ServiceManifestName="Stateful1Pkg" ServiceManifestVersion="1.0.0" />
  <ConfigOverrides>
    <!-- こんな感じ -->
    <ConfigOverride Name="Config">
      <Settings>
        <Section Name="UserDatabase">
          <Parameter Name="ConnectionString" Value="[ConnectionString]" />
        </Section>
      </Settings>
    </ConfigOverride>
  </ConfigOverrides>
  <!-- ServicePackage から ServiceManifest をインポートします。ServiceManifestName と ServiceManifestVersion は、
     ServiceManifest.xml ファイルで定義されている ServiceManifest 要素の [Name] 属性と [Version] 属性と 
     一致しなければなりません。-->
</ServiceManifestImport>

そして、同じファイルのParametersタグに先ほど追加したかっこで囲ったパラメータ名のパラメータを追加します。

<Parameters>
  <Parameter Name="Stateful1_MinReplicaSetSize" DefaultValue="3" />
  <Parameter Name="Stateful1_PartitionCount" DefaultValue="1" />
  <Parameter Name="Stateful1_TargetReplicaSetSize" DefaultValue="3" />
  <Parameter Name="Stateless1_InstanceCount" DefaultValue="-1" />
  <!-- これを追加 -->
  <Parameter Name="ConnectionString" DefaultValue="DefaultConnectionString" />
</Parameters>

Step3

アプリケーションのプロジェクトのAplicationParametersフォルダの下にある構成単位のxmlファイルの中身を構成に合わせて設定します。 Local.Node1.xmlやLocal.Node5.xmlの場合はローカルDBの接続文字列とか、Cloud.xmlはSQL Databaseとかいった感じです。

こんな風になります。

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/Application1" xmlns="http://schemas.microsoft.com/2011/01/fabric">
  <Parameters>
    <Parameter Name="Stateful1_PartitionCount" Value="1" />
    <Parameter Name="Stateful1_MinReplicaSetSize" Value="1" />
    <Parameter Name="Stateful1_TargetReplicaSetSize" Value="1" />
    <Parameter Name="Stateless1_InstanceCount" Value="1" />
    <!-- これを追加 -->
    <Parameter Name="ConnectionString" Value="Node1ConnectionString" />
  </Parameters>
</Application>

Step4

定義は完了です。あとはコードからの参照方法ですが以下のようなコードで出来ます。

this.Context
  .CodePackageActivationContext
  .GetConfigurationPackageObject("Config")
  .Settings
  .Sections["UserDatabase"]
  .Parameters["ConnectionString"]
  .Value

長いですね。記述場所はStatefulやStatelesの中になります。Contextにアクセスできれば何処で書いてもOKです。