Substituting multiple variables in a list using a VSTS Release Definition - azure-devops

I am currently using variable substitution in VSTS however I have hit a roadblock on how to select specific elements from a list.
I must supply both a name for the variable I want to substitute and a key with which to substitute the old value. I can use . to select nested elements in config.
I have the following app.config.
<services>
<service behaviorConfiguration="ServiceBehaviour" name="Application.Project01">
<endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" bindingConfiguration="web" contract="Application.Interface01">
<identity>
<dns value="dns01" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/Project01/" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="ServiceBehaviour" name="Application.Project02">
<endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" bindingConfiguration="web" contract="Application.Interface02">
<identity>
<dns value="dns01" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/Project02/" />
</baseAddresses>
</host>
</service>
</services>
I would like to be able to substitute variables in each one of these services individually. The specific keys I am interested in are services.service.endpoint.identity.dns.value and services.host.baseaddresses.add.baseaddress.
I have tried the following to edit the dns value
services.1.service.endpoint.identity.dns
services.1.service.endpoint.identity.dns.value
The task that I am using is the Azure App Service Deploy version 3.*

For XML variable substitution feature of Azure App Service Deploy task, it takes effect only on the applicationSettings, appSettings, connectionStrings, and configSections elements of configuration files.
So you can’t use it to achieve your requirement.
You can try it with XML Transformation.
You also can try it with other tasks, such as Release Management Utility tasks or others.

Related

Bad Request REST/SOAP for a WCF Webservice

A WCF service needs to be capable to SOAP and REST format.
It returns Bad Request (400), below is my web config file:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ILoginSVC" allowCookies="true" maxBufferPoolSize="20000000" maxBufferSize="70000000" maxReceivedMessageSize="70000000">
</binding>
</basicHttpBinding>
<webHttpBinding>
<binding name="webHttpBindingILoginSVC" allowCookies="true" maxBufferSize="100000000" maxBufferPoolSize="100000000" maxReceivedMessageSize="100000000" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<services>
<service name="LoginSVC.LoginSVC">
<host>
<baseAddresses>
<add baseAddress="http://localhost:59900/LoginSVC" />
</baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="LoginSVC.ILoginSVC">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="REST" binding="webHttpBinding" contract="LoginSVC.ILoginSVC" behaviorConfiguration="RESTEndPointBehaviour">
</endpoint>
</service>
</services>
</system.serviceModel>
In your configuration file, you have not assigned the binding configuration you created, so use the default BasicHttpBinding. You need to explicitly assign the binding you defined (BasicHttpBinding_ILoginSVC) to your endpoint like this:
<endpoint address="" bindingConfiguration="BasicHttpBinding_ILoginSVC" binding="basicHttpBinding" contract="LoginSVC.ILoginSVC" />

Self Hosted (console) WCF configuration

i had a WCF server running through a Console application, it will run as an azure service so i don't to host it in ISS.
I belived it work well and share datas to my web app through ajax request. But when i maked a service that recieve a filestream, i realized that my binding configuration is not used at all. My WCF work same without binding section.
My probleme concerne especially the key "maxReceivedMessageSize" because default value limit me to 8Ko request and it is a problem for uploading file.
Bindings section (that i can comment) :
<webHttpBinding>
<binding name="MyBindingConfig" crossDomainScriptAccessEnabled="true" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" transferMode="Buffered">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None" />
</binding>
</webHttpBinding>
Services section :
<service name="MyData.Service.MyDataServiceRestFull">
<endpoint binding="webHttpBinding"
contract="MyData.Service.IMyDataServiceRestFull" bindingName="MyBindingConfig" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9997/MyDataServer"/>
</baseAddresses>
</host>
</service>
Note that i tryed with basicHttpBinding and i had same issue.
The problem is that you're incorrectly referring to your binding in your <endpoint/> element. You're using the bindingName attribute, when you should be using the bindingConfiguration attribute:
<endpoint binding="webHttpBinding"
contract="MyData.Service.IMyDataServiceRestFull"
bindingConfiguration="MyBindingConfig" />

What do the EndPoints configure in the ServiceManifest of an Service Fabric Service?

We have a Service Fabric Service project with multiple services: Actors, Stateful services and Stateless services combined into one ServiceManifest.
Two stateful services did not work: the constructors were called, the communicationlisteners (through remoting) were created, but the RunAsync method was not called.
After removing the endpoint listing from the ServiceManifest.xml the services started working again. But now we are left wondering why and how this works. Could someone explain?
To illustrate, the relevant section was
<Resources>
<Endpoints>
<Endpoint Name="WebServiceEndpoint" Type="Input" Protocol="http" Port="80" />
<Endpoint Name="StatelessServiceEndpoint1" Type="Input" Protocol="http" Port="10101" />
<Endpoint Name="ActorServiceEndpoint1" />
<Endpoint Name="ActorServiceReplicatorEndpoint1" />
<Endpoint Name="ActorServiceEndpoint2" />
<Endpoint Name="ActorServiceReplicatorEndpoint2" />
<Endpoint Name="ActorServiceEndpoint3" />
<Endpoint Name="ActorServiceReplicatorEndpoint3" />
<Endpoint Name="ActorServiceEndpoint4" />
<Endpoint Name="ActorServiceReplicatorEndpoint4" />
<Endpoint Name="StatefulServiceEndpoint1" Type="Input" Protocol="http" />
<Endpoint Name="StatefulServiceReplicatorEndpoint1" />
<Endpoint Name="StatefulServiceEndpoint2" Type="Input" Protocol="http" />
<Endpoint Name="StatefulServiceReplicatorEndpoint2" />
<Endpoint Name="StatelessServiceEndPoint2" Type="Input" Protocol="http" />
</Endpoints>
</Resources>
After changing it to this
<Resources>
<Endpoints>
<Endpoint Name="WebServiceEndpoint" Type="Input" Protocol="http" Port="80" />
<Endpoint Name="StatelessServiceEndpoint1" Protocol="http" />
<Endpoint Name="ActorServiceReplicatorEndpoint1" />
<Endpoint Name="ActorServiceReplicatorEndpoint2" />
<Endpoint Name="ActorServiceReplicatorEndpoint3" />
<Endpoint Name="ActorServiceReplicatorEndpoint4" />
<Endpoint Name="StatefulServiceReplicatorEndpoint1" />
<Endpoint Name="StatefulServiceReplicatorEndpoint2" />
</Endpoints>
</Resources>
everything worked. But why?
EDIT
The complete ServiceManifest is this:
<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Service" Version="1.0.0"
xmlns="http://schemas.microsoft.com/2011/01/fabric"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServiceTypes>
<StatefulServiceType ServiceTypeName="ActorService1Type" />
<StatefulServiceType ServiceTypeName="ActorService1Type" HasPersistedState="true" />
<StatefulServiceType ServiceTypeName="ActorService3Type" />
<StatefulServiceType ServiceTypeName="ActorService4Type" HasPersistedState="true" />
<StatefulServiceType ServiceTypeName="StatefulService1Type" HasPersistedState="true" />
<StatefulServiceType ServiceTypeName="StatefulService2Type" HasPersistedState="true" />
<StatelessServiceType ServiceTypeName="StatelessService1Type" />
<StatelessServiceType ServiceTypeName="StatelessService2Type" />
<StatelessServiceType ServiceTypeName="WebServiceType" />
</ServiceTypes>
<CodePackage Name="Code" Version="1.0.0">
<SetupEntryPoint>
<ExeHost>
<Program>Setup.exe</Program>
</ExeHost>
</SetupEntryPoint>
<EntryPoint>
<ExeHost>
<Program>Service.exe</Program>
</ExeHost>
</EntryPoint>
</CodePackage>
<ConfigPackage Name="Config" Version="1.0.0" />
<Resources>
<Endpoints>
<Endpoint Name="WebServiceEndpoint" Type="Input" Protocol="http" Port="80" />
<Endpoint Name="StatelessServiceEndpoint1" Protocol="http" />
<Endpoint Name="ActorServiceReplicatorEndpoint1" />
<Endpoint Name="ActorServiceReplicatorEndpoint2" />
<Endpoint Name="ActorServiceReplicatorEndpoint3" />
<Endpoint Name="ActorServiceReplicatorEndpoint4" />
<Endpoint Name="StatefulServiceReplicatorEndpoint1" />
<Endpoint Name="StatefulServiceReplicatorEndpoint2" />
</Endpoints>
</Resources>
</ServiceManifest>
Hard to know what happened in your initial reported case since there's no specific error or error message to work off of, but usually this is port conflicts when you end up sharing ports that you don't really want to or which can't be shared, or port exhaustion.
The endpoint resource in your service manifest is mainly for times when:
you want SF to help with allocating communication resources like ports for your services
you want SF to help configure those resources:
Allocating some port and consistently assigning it to some set of workloads
Punching a hole in the local firewall
Setting up a URLACL (relevant to http on windows through http.sys only)
Setting up and configuring certs to enable secure communication (same caveat)
In general you're free to ignore the endpoint resource if you don't need/want the help, since SF really is expecting the service code to do it's setup. In cases where you're not really using SF's programming models then the endpoint resource is more important since it's how you communicate to SF what your endpoints are.
The behavior you get really depends on the transport you're using, as well as the OS's dynamic port range and the Application port range that you've defined, as well as what the service code actually does.
https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-fabric-settings#section-name-fabricnode
Let's say you're setting up an http communication listener in your service like so, and walk through a few examples of what happens when you define and endpoint in your manifest or don't.
1) Let's say you put nothing in your service manifest about endpoints. This means that effectively you're specifying 0 as the port in code. In this case SF's not doing any allocation or management. The port is getting assigned by the OS from the OS dynamic port range. The port that actually gets assigned will be different for each service instance listener. This should work as a reasonable default choice in most scenarios.
2) Let's say you're specifying an endpoint in the manifest and not specifying any port at all, i.e.:
<Endpoint Name="HealthServiceEndpoint"/>
In this case, the port that is assigned will come from the SF application port range. It will be the same for any service instances hosted in the same process, but different across processes. (So it matters if you are using the Exclusive or Shared process hosting model) This also presumes that reusing the port is supported for your transport. Most transports don't (like http on via Kestrel in .NET, TCP under most cases), but there are some notable examples (http.sys based http transports on Windows like WebListener/HttpSys, tcp via net.tcp in WCF probably a few others).
3) Let's say you're specifying an endpoint in the service fabric manifest and explicitly specifying 0 for that port i.e.:
<Endpoint Name="HealthServiceEndpoint" Port="0" Protocol="http"/>
In this case the port that gets assigned will be from the OS dynamic port range, and it will end up the same/shared for any service instances hosted in the same process that use that endpoint. The port will be different across processes. (So again it matters if you are using the Exclusive or Shared process hosting model)
4) Naturally if the endpoint is specified and a specific port is specified, that port will be used for all service instances both within and across processes. This somewhat implicitly assumes that such sharing is going to work, which again depends on your transport and platform, or that you're never planning on running more than one instance of the service on this node.
Other trivia:
the "transport" element mainly determines whether SF registers your url with http.sys on windows or configures certificates to secure traffic (most of this can be done within your service code or a SetupEntryPoint).
as of this writing Type is ignored (this is a holdover from an older version of SF)
PathSuffix is used to create a default uri fragment that gets appended to the IP and port assigned by the platform. This is used in cases where there's code not using SF's listener APIs that sets up some listener on a different path like /api/value, like a the code inside a container might do.

dotnetopenauth Provider WebConfig Error

I am required to create a provider using the DNOA. I have downloaded the libraries from the DNOA site and attempted to load the oAuthServiceProvider example. I couldn't load this as this is looking for
\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets"
which is part of Visual Studio 2010, I however am on 2008. Despite changing the version to v9.0 it was still looking for v10.0. Nevermind.
I open the project as a website and tried to run this. But now get the error "Error 1 Unrecognized configuration section uri."
Any ideas as to what is going on here? Below is the webconfig
<?xml version="1.0"?>
<!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
which is necessary for OpenID urls with unicode characters in the domain/host name.
It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
<uri>
<idn enabled="All"/>
<iriParsing enabled="true"/>
</uri>
<system.net>
<defaultProxy enabled="true" />
<settings>
<!-- This setting causes .NET to check certificate revocation lists (CRL)
before trusting HTTPS certificates. But this setting tends to not
be allowed in shared hosting environments. -->
<!--<servicePointManager checkCertificateRevocationList="true"/>-->
</settings>
</system.net>
<!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
<dotNetOpenAuth>
<!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
<reporting enabled="true" />
<messaging>
<untrustedWebRequest>
<whitelistHosts>
<add name="localhost"/>
</whitelistHosts>
</untrustedWebRequest>
</messaging>
</dotNetOpenAuth>
<appSettings/>
<connectionStrings>
<system.web>
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<compilation debug="true" targetFramework="4.0">
<assemblies>
<remove assembly="DotNetOpenAuth.Contracts"/>
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
<authentication mode="Forms">
<forms name="oauthSP" />
</authentication>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
</system.web>
<!--
The system.webServer section is required for running ASP.NET AJAX under Internet
Information Services 7.0. It is not necessary for previous version of IIS.
-->
<log4net>
<appender name="TracePageAppender" type="OAuthServiceProvider.Code.TracePageAppender, OAuthServiceProvider">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>
<!-- Setup the root category, add the appenders and set the default level -->
<root>
<level value="INFO"/>
<!--<appender-ref ref="RollingFileAppender" />-->
<appender-ref ref="TracePageAppender"/>
</root>
<!-- Specify the level for some specific categories -->
<logger name="DotNetOpenAuth">
<level value="ALL"/>
</logger>
</log4net>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="DataApiBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceAuthorization serviceAuthorizationManagerType="OAuthServiceProvider.Code.OAuthAuthorizationManager, OAuthServiceProvider" principalPermissionMode="Custom"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="DataApiBehavior" name="OAuthServiceProvider.DataApi">
<endpoint address="" binding="wsHttpBinding" contract="OAuthServiceProvider.Code.IDataApi">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>

Web.config transformation: how to apply a transformation to all node matching a Locator expression?

I've recently discovered the web.config automatic transformation in the web deploy tool of visual studio 2010.
It's working well, but I have a scenario I can't seem to get working.
Assume I have the following root Web.config
<services>
<service name="Service1">
<endpoint address="" binding="customBinding" bindingConfiguration="LargeBufferBinding"
contract="Service1" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service name="Service2">
<endpoint address="" binding="customBinding" bindingConfiguration="LargeBufferBinding"
contract="Service2" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<service name="Service3">
<endpoint address="" binding="customBinding" bindingConfiguration="LargeBufferBinding"
contract="Service3" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
For my Web.Release.config, I want all the endpoint nodes with a binding of mexHttpBinding to be removed.
I've used the following in my Web.Release.config:
<services>
<service>
<endpoint binding="mexHttpBinding" xdt:Locator="Match(binding)" xdt:Transform="Remove" />
</service>
</services>
However, this will only remove the first match, in the Service1, but not the following ones.
I've tried various way of locating the node, on the endpoint and service node, but only the first match ever gets replaced.
Is there a way to get all the <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> to be removed ?
Thanks.
I've just tried this and using RemoveAll instead of Remove seems to do the trick:
<services>
<service>
<endpoint binding="mexHttpBinding" xdt:Locator="Match(binding)" xdt:Transform="RemoveAll" />
</service>
</services>