3

I have an ApplicationManifest.xml file that looks like:

<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest 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"
   ApplicationTypeName="ServiceFabricTestType" ApplicationTypeVersion="1.9">
   <Parameters>
     <Parameter Name="Prop_BehavioursPath" DefaultValue="behaviours.yml"/>
     <Parameter Name="Prop_AliasesPath" DefaultValue="aliases.yml"/>
   </Parameters>
  <ServiceManifestImport>
  <ServiceManifestRef 
    ServiceManifestName="SummaryGenerator" 
    ServiceManifestVersion="1.9.0.0" 
    />
  </ServiceManifestImport>
</ApplicationManifest>

And I want to use the parameters to adjust the Argument of my guest hosted service, declared in a ServiceManifest.xml file like so:

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest 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"
   Name="SummaryGenerator" Version="1.9.0.0">
   <ServiceTypes>
     <StatelessServiceType ServiceTypeName="SummaryGenerator" UseImplicitHost="true"/>
   </ServiceTypes>
   <CodePackage Name="code" Version="1.9.0.0">
   <EntryPoint>
     <ExeHost>
        <Program>MyProgram.exe</Program>
        <Arguments>&quot;LoadFrom=[Prop_AliasesPath]|[Prop_BehavioursPath]&quot;</Arguments>
        <ConsoleRedirection FileRetentionCount="5" FileMaxSizeInKb="2048"/>
     </ExeHost>
   </EntryPoint>
  </CodePackage>
</ServiceManifest>

This clearly doesn't work as the properties going into the Arguments are treated as verbatim and not resolved from the parameter values.

What I really want to do is to be able to start a service and pass in different values for Prop_BehavioursPath and Prop_AliasesPath. Is there a better way to do this in Service Fabric?

The application being run doesn't know about Service Fabric and the only way to push configuration through to it is via the command arguments.

tommed
  • 1,521
  • 2
  • 19
  • 33

2 Answers2

3

Doesn't look like you can do that... Instead, you could try a workaround where you write a small .NET wrapper that reads the sf configuration and then launches your guest executable. You could redirect stdin/stdout from the child process and hook into it's exited event as well so the main process terminates when the child terminates.

Raghu
  • 1,140
  • 1
  • 14
  • 22
  • 1
    Love the idea of using the decorator pattern to abstract the runtime further, this is definitely the solution I was looking for! – tommed May 28 '16 at 13:57
  • Would love to see it if you do get around to it... since all it's doing is launching a process, it should work for anything. – Raghu May 28 '16 at 14:01
  • I'll post an answer here if I find a more direct route – tommed May 28 '16 at 14:04
  • @tommed have you found a more direct route? I currently face the same problem. – Robar Apr 17 '18 at 12:21
  • 1
    Nah, due to lack of response, I am using Kubernetes instead now as my infrastructure and really happy with the service/community/support/documentation – tommed Apr 22 '18 at 22:21
1

Similar to parameters, you can define environment variables (say Prop_AliasesPath andProp_BehavioursPath) in ServiceManifest.xml and then override their values in ApplicationManifest.xml. Then you have two options:

Option 1: Even if your entry point MyProgram.exe is not service fabric aware, it can read the environment variables.

Option 2: To avoid reading environment variables inside MyProgram.exe, you can use a batch file as a entry point and from it call "MyProgram.exe LoadFrom=%Prop_AliasesPath%%Prop_BehavioursPath%"

More info about overriding Environment Variables: https://dzimchuk.net/using-code-package-environment-variables-in-service-fabric/