Preprocess BRE Policy and Vocabulary files

Topics: Bindings File, Settings Management and SSO
Aug 23, 2012 at 12:35 PM

Hi,

I have a requirement to preprocess a vocabulary file to allow a field to pick values based on the environment. I have added the placeholder in the vocabulary xml and also updated the SettingsFileGenerator.

Further, I made following additions to the bdtfproj file, as suggested by you here.



<ItemGroup>
    <AdditionalFiles Include="myVocab.xml">      
        <LocationPath>..\BRE\Vocabularies</LocationPath>
    </AdditionalFiles>
  </ItemGroup>

  <!-- adding additional files for XML pre-processing-->

  <ItemGroup>
    <FilesToXmlPreprocess Include="myVocab.xml">
      <LocationPath>..\BRE\Vocabularies</LocationPath>
    </FilesToXmlPreprocess>
  </ItemGroup>
  
  <Target Name="CustomDeployTarget" Condition="'$(Configuration)' == 'Server'">

    <copy sourceFiles="..\myVocab.xml" DestinationFolder="..\BRE\Vocabularies"/>
  </Target>   

When i am trying to deploy the project, i get the following error:

PreprocessFiles:
  "C:\Program Files (x86)\Deployment Framework for BizTalk\5.0\Framework\DeployTools\xmlpreprocess.exe" /f /v  /i:"" /o:"" /d:CurDir="" /s:"\.Deployment\EnvironmentSettings\Exported_LocalSettings.xml"
  XmlPreprocess v2.0.13.0
  Copyright (c) 2004-2010 Loren M Halvorson
  XML File Preprocessor
  
  /i:: Argument expects a parameter

Please suggest what changes should be made to make this work. Thanks in advance for your help!

Pratish

Aug 24, 2012 at 5:35 AM

Hi,

The issue got resolved. It was all due to ignoring the order in which the activities had to be performed.

BTW, it has been a good experience exploring BTDF as a deployment tool for BizTalk interfaces and would like to thank Tom and his team for this wonderfull effort.

Regards,

Pratish

 

Coordinator
Aug 29, 2012 at 5:53 AM

Hi Pratish,

Glad to hear that you got it working and that you've been happy with the Deployment Framework so far!  Thanks for that feedback.  I wish there was a team here to help out, but it's really just me.  :-)

Thanks,
Tom

Apr 4, 2013 at 11:54 AM
Edited Apr 9, 2013 at 12:16 PM
I am trying to preprocess a policy and I am getting the same error (/i:: Argument expects a parameter).

Can you tell me where and in which order i should put this:
  <Target Name="CustomDeployTarget" Condition="'$(Configuration)' == 'Server'">
    <Copy sourceFiles="..\$(ProjectName).Policy.xml" DestinationFolder="..\BRE"/>
  </Target>

  <ItemGroup>
    <FilesToXmlPreprocess Include="$(ProjectName).Policy.xml">
      <LocationPath>..\BRE</LocationPath>
    </FilesToXmlPreprocess>
  </ItemGroup>

  <ItemGroup>
    <AdditionalFiles Include="$(ProjectName).Policy.xml">
      <LocationPath>..\BRE</LocationPath>
    </AdditionalFiles>
  </ItemGroup>

  <ItemGroup>
    <RulePolicies Include="$(ProjectName).Policy.xml">
      <LocationPath>..\BRE</LocationPath>
    </RulePolicies>
  </ItemGroup>
EDIT:

Nevermind. It's working now. This is the order i have it in now:
  <ItemGroup>
    <AdditionalFiles Include="$(ProjectName).Policy.xml">
      <LocationPath>..\BRE\Policies</LocationPath>
    </AdditionalFiles>
  </ItemGroup>
  <ItemGroup>
    <FilesToXmlPreprocess Include="$(ProjectName).Policy.xml">
      <LocationPath>..\BRE\Policies</LocationPath>
    </FilesToXmlPreprocess>
  </ItemGroup>  
  <ItemGroup>
    <RulePolicies Include="$(ProjectName).Policy.xml">
      <LocationPath>..\BRE\Policies</LocationPath>
    </RulePolicies>
  </ItemGroup>

... other stuff...

  <Target Name="CustomDeployTarget" Condition="'$(Configuration)' == 'Server'">
    <Copy sourceFiles="..\$(ProjectName).Policy.xml" DestinationFolder="..\BRE\Policies"/>
  </Target>
John Viggo
Coordinator
Apr 11, 2013 at 5:32 AM
Hi John,

One other thing to avoid having a potentially source-controlled and read-only file be modified every time this is run on a dev machine. FilesToXmlPreprocess has another metadata element named OutputFilename. Assuming that your policy XML file is stored in source control and normally read-only, you can use OutputFilename to leave your original/template file untouched:
  <ItemGroup>
    <FilesToXmlPreprocess Include="$(ProjectName).PolicyMaster.xml">
      <LocationPath>..\BRE\Policies</LocationPath>
      <OutputFilename>$(ProjectName).Policy.xml</OutputFilename>
    </FilesToXmlPreprocess>
  </ItemGroup>  
In this case your AdditionalFiles and CustomDeployTarget references would be to $(ProjectName).PolicyMaster.xml. This would be a bit simpler if AdditionalFiles preserved the directory structure when it copies files into the MSI folder structure...

Thanks,
Tom
Sep 13, 2013 at 6:41 AM
Edited Sep 13, 2013 at 6:45 AM
Using the OutputFilename is supposed to write the output next to the source file. That does not seem to work for me, as the result of the processed masterFile is never found in the directory of the masterfile. The result of the processed file (ItenarySelection.xml) can be found in the root of the targetdirectory. I import this policy manually from that directory after deployment. Why is the OutputFilename not created where it is supposed to?

Here is an outline of my script.

<ItemGroup>
<AdditionalFiles Include="ItenarySelection.Master.xml">
  <LocationPath>..\BRE\VocabAndRules</LocationPath>
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<FilesToXmlPreprocess Include="ItenarySelection.Master.xml">
  <LocationPath>..\BRE\VocabAndRules</LocationPath>
  <OutputFilename>ItenarySelection.xml</OutputFilename>
</FilesToXmlPreprocess>
</ItemGroup>

<ItemGroup>
<RulePolicies Include="ItenarySelection.xml">
  <LocationPath>..\BRE\VocabAndRules</LocationPath>
</RulePolicies>
</ItemGroup>
Coordinator
Sep 13, 2013 at 3:16 PM
On a Visual Studio deployment, the preprocessed file should appear next to the source file. On a server deployment via MSI, the source file ItenarySelection.Master.xml will no longer be in a subfolder, but instead in the main install folder, so that is also where the preprocessed file will appear. If you want it to always be in the same folder, you can add something like this:
<Target Name="CopyPreprocessedPolicy" AfterTargets="PreprocessFiles" Condition="'$(Configuration)' == 'Server'">
  <ItemGroup>
    <PolicyToCopy Include="..\ItenarySelection.xml" />
  </ItemGroup>

  <Copy DestinationFolder="..\BRE\Policies" SourceFiles="@(PolicyToCopy)" />
</Target>
I haven't tested it, so you may have to tweak the Copy task. This will copy the preprocessed file into BRE\Policies only on a server install. It should be close to a complete solution.

Thanks,
Tom
Sep 14, 2013 at 7:27 AM
What I am trying to achieve, is that in a server deployment via the MSI, the policies would automatically be imported and deployed. This is what the

<RulePolicies Include="ItenarySelection.xml">
<LocationPath>..\BRE\VocabAndRules</LocationPath>
</RulePolicies>

inclusion does for a Visual Studio deployment.

Like you said, the preprocessed file is installed in the main install folder. I haven't found a way to use the RulePolicies tag in combination with the preprocessed file in in main install folder, even an abolute path reference gives mixed results. I was looking for a macro for the main install folder but haven't found something suitable. Maybe the deployment of policies in a server deployment via the MSI is achieved in another way?
Coordinator
Sep 15, 2013 at 5:49 AM
I realized what you were trying to do from your first post, and that's why I posted the solution above. Did you try it? The point of it is to copy the file to the BRE\VocabAndRules folder after it is preprocessed, and only on a server deployment.

Another option is to add the Condition attribute to the ItemGroup containing the RulePolicies item, and have two copies, one that matches the condition for a server deploy and has the path .., and one that matches the condition for a VS deploy and has the path ..\BRE\Policies.

This is all just MSBuild, so there are numerous ways to solve the problem, and I've only mentioned two (one here, one in previous post).

Thanks,
Tom
Sep 16, 2013 at 6:27 AM
Edited Sep 16, 2013 at 7:34 AM
Hello Tom,

I tried the solution from your first post and it worked like a charm. Why it works was not clear for me initially, but I assume now that rules that are copied to the BRE\Policies directory are deployed by default.
Thanks for your help,

Best regards,
Peter
Coordinator
Sep 16, 2013 at 7:04 AM
Hi Peter,

It's not that they are deployed by default from BRE\Policies. That's what you used in your ItemGroup. This solution is just getting the file into the same place during a server deploy as it's in for a Visual Studio deployment.

Tom
Dec 9, 2013 at 9:13 PM
Hello Tom
I believe I'm running into a similar issue which is being discussed here. The MSI install works however it doesn't deploy the policy.

Kindly let me know what settings I've to do to make the dynamic policy working.
Here is an excerpt from the dtdfproj file.

...
<IncludeVocabAndRules>true</IncludeVocabAndRules>
<RequireXmlPreprocessDirectives>false</RequireXmlPreprocessDirectives>
<EnableXmlPreprocess>true</EnableXmlPreprocess>

...

  <ItemGroup>
    <AdditionalFiles Include="$(ProjectName).Config.Policy.Template.xml">
      <LocationPath>..\$(ProjectName).Policies</LocationPath>
    </AdditionalFiles>
  </ItemGroup>
  <ItemGroup>
    <FilesToXmlPreprocess Include="$(ProjectName).Config.Policy.Template.xml">
      <LocationPath>..\BRE\Policies</LocationPath>
      <OutputFilename>$(ProjectName).Config.Policy.xml</OutputFilename>
    </FilesToXmlPreprocess>
  </ItemGroup>
  <ItemGroup>
    <RulePolicies Include="$(ProjectName).Config.Policy.xml">
      <LocationPath>..\BRE\Policies</LocationPath>
    </RulePolicies>
  </ItemGroup>

  <!-- !!! TODO !!! -->
  <Import Project="$(DeploymentFrameworkTargetsPath)BizTalkDeploymentFramework.targets" />
  <!--
    The Deployment Framework automatically packages most files into the server install MSI.
    However, if there are special folders that you need to include in the MSI, you can
    copy them to the folder $(RedistDir) in the CustomRedist target.
    To include individual files, add an ItemGroup with AdditionalFiles elements.
  -->
  <Target Name="CustomDeployTarget" Condition="'$(Configuration)' == 'Server'">
    <Copy sourceFiles="..\$(ProjectName).Config.Policy.Template.xml" DestinationFolder="..\BRE\Policies" />
  </Target>

  <Target Name="CustomRedist">
  </Target>
Thanks in advance for your help.

Best Regards,
Tahir
Coordinator
Dec 10, 2013 at 7:23 PM
When the XmlPreprocess step runs on an MSI deploy, it actually ignores the LocationPath. You were very close in your original state.

Remove the CopyPolicyTemplate target again, and add this back in:
  <Target Name="CustomDeployTarget" Condition="'$(Configuration)' == 'Server'">
    <Copy sourceFiles="..\$(ProjectName).Config.Policy.xml" DestinationFolder="..\BRE\Policies" />
  </Target>
The only difference is to copy $(ProjectName).Config.Policy.xml not $(ProjectName).Config.Policy.Template.xml into your ..\BRE\Policies folder.

When you try the next deploy, check that ..\$(ProjectName).Config.Policy.xml is being created and that is has been preprocessed, and check that $(ProjectName).Config.Policy.xml has been copied into ..\BRE\Policies. It should then be picked up by the RulePolicies ItemGroup.

Sorry for the wrong turn. I'm going to delete my previous reply so it doesn't cause future confusion.

Thanks,
Tom
Dec 11, 2013 at 4:20 PM
Thanks Tom, I added few more policies and vocabularies. It works like a charm.

Best Regards,
Tahir