Cannot Upgrade with Existing Functions - azure

Create a new Azure Function App from the Azure Portal. Add a new function to it. You will be presented with a warning icon with the following text:
Cannot Upgrade with Existing Functions
Major version upgrades can introduce breaking changes to languages and bindings. When upgrading major versions of the runtime, consider creating a new function app and migrate your functions to this new app.
My question is what action is required? Is it simply a warning that a future upgrade might cause issues? Perhaps is it related to the GitHub commentary about new template versions in Visual Studio
Note: deleting the all functions from the function app, causes the issue to disappear.

You are right, it's just a tip for you to refer, no action required.
When you create a function app in portal, the app uses the runtime ~1 by default.
Before you create any function in the app, you are allowed to change the runtime version in the function app settings panel.
After that, it's not recommended and also not allowed to change as the button is grey in this panel, with the warning you see. Because the runtime upgrade may cause error to your code depending on the specific runtime.
And as you see, once no function exists in the app, the warning disappears and is able to change the runtime again.
The application settings panel allows us to change FUNCTIONS_EXTENSION_VERSION (i.e. the runtime)between ~1 and beta despite existing functions, but still remember the runtime switch may cause breaking changes.
Update
Preview beta runtime has been GA and corresponding FUNCTIONS_EXTENSION_VERSION is changed to ~2, when we create a function app, default runtime is changed to ~2 as well.

The warning is there so you wouldn't go and possibly break your current v1 functions when upgrading the runtime to v2.
Consider for example the following code examples:
V2 template:
[FunctionName('Function1')]
public static IActionResult Run([HttpTrigger(AuthorizationLevel.Function, 'get', 'post', Route = null)]HttpRequest req, TraceWriter log)
{
V1 template:
[FunctionName('Function1')]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, 'post', Route = null)]
HttpRequestMessage req,
TraceWriter log)
These two function definitions use different versions of the runtime.
If you'd, at the press of a button, go and update the runtime, then you'd break your code. Hence the suggestion, create a new function app entirely using the new version and migrate your code to it instead of just updating the runtime.
Code snippet I found here.

Related

Azure Functions v3 Could not load file or assembly 'Microsoft.Extensions.Primitives, Version=5.0.0.0

I'm having the above error after running an azure function called "Test" that redirects to an external URL of a service we want to use.
[FunctionName("Test")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequest req)
{
Log.Information("C# HTTP trigger function processed a request.");
string url = _authenticationService.GetAuthorizationUri().ToString();
return new RedirectResult(url);
}
The site at the URL prompts the user to authorize use of their data and performs a redirect to the previously authorized url of our "AuthorizationCallback", along with a query string parameter.
[FunctionName("AuthorizationCallback")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
{
Log.Information("C# HTTP trigger function processed a request.");
string code = req.Query["code"];
try
{
if (!string.IsNullOrEmpty(code))
{
await _authenticationService.ExchangeCodeForAccessToken(code);
return new OkResult();
}
}
catch (System.Exception)
{
return new UnauthorizedResult();
}
return new NotFoundResult();
}
The AuthorizationCallback function is hit but produces the following error in the console:
These are the dependencies of the current project on the solution (which is set as the startup project):
I've tried installing both the latest stable version (5.0.0) and the version before that (3.1.13) of Microsoft.Extensions.Primitives in the current project, but I'm still getting the same error. I've noticed the package that can't be loaded is within microsoft.azure.webjobs (3.0.23), which is within microsoft.azure.webjobs.extensions.storage (4.0.4), but these are used in another project entirely, for another azure function (blob triggered). Any ideas on how to overcome this error? Thank you all.
The Azure Functions host for .NET Core 3 uses an in-process hosting model, which essentially means you are limited in what versions of Microsoft assemblies you can use. What's happening is that something in your project has a reference to a newer version of Microsoft.Extensions.Primitives, but an older version of that library is already loaded by the Azure Functions host application.
For Azure Functions .NET Core 3, you should restrict all Microsoft.Extensions.* libraries to v3.x. You currently have Microsoft.Extensions.DependencyInjection 5.0.1, which should be changed to 3.x. Check for any other Microsoft.Extensions.* libraries either at the Packages level or anywhere beneath (tip: you can find them quickly by putting Microsoft.Extensions in the input box at the top of the Solution Explorer). You may need to downgrade some other library that has Microsoft.Extensions.Primitives as a dependency.
You might also be able to get away with manually writing a bindingRedirect pointing the newer version to an older version. The Microsoft.Extensions.* packages are relatively stable across versions, so that may work. It would make me very nervous, though.

Disable certain Azure functions using any configuration

While using Azure functions, I have a situation where I want a few functions in "disabled" mode for a function app, while others to be enabled. The thing is, I don't want to do it manually using the functions screen where individual functions could be enabled/disabled easily. There is this article that says Functions 2.x supports this (Functions 1.x is not a choice for me).
https://learn.microsoft.com/en-us/azure/azure-functions/disable-function
It is just that the article is a little vague about what needs to be done. It says and I quote >
In Functions 2.x you disable a function by using an app setting. For example, to disable a function named QueueTrigger, you create an app setting named AzureWebJobs.QueueTrigger.Disabled, and set it to true. To enable the function, set the app setting to false.
I tried this, but it doesn't work as documented. I have a function app called foo and a function called bar. I have tried both:
disabled: true in function.json
as well as:
foo: {
bar: {
disabled: true
}
}
After making these changes and redeploying there is no effect on the UI. What am I missing?
The recommended approach is by using app settings, which you can do by going to the portal. [Note: They don't mean function.json when they say app settings.]
Option 1: Using App Settings
In azure portal, navigate to your function app foo -> Confuguration, and you should see Application Settings tab with a few variables already defined. You need to create a new variable by clicking New application setting button. Set name as AzureWebJobs.bar.Disabled and value as true. Note that the function app name foo doesn't figure in the variable name.
Option 2: Using host.json
Because you are looking for disabling a function from code, you can try doing this in host.json. Note that this is intended for local development, and not recommended for prod, but it works.
https://learn.microsoft.com/en-us/azure/azure-functions/functions-host-json#functions
{
"functions": [ "function1", "function2" ] // Don't list function "bar" here, and it would get disabled.
}
Note that the portal will not show this correctly, and list "bar" as enabled, but you will get 404 when hitting that function.
Option 3: Using Disable attribute
If you are using C# You can also use the [Disable] attribute. This is a Functions 1.x construct, but it works in 2.x as well. Similar to above, the portal UI will not show this correctly.
[Disable]
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
}
Option 4: By removing FunctionName attribute
Only if you are using C#. This might sound counter-intuitive, but if you remove the FunctionName attribute from your function, it won't be treated as such.
// [FunctionName("Function1")] // Comment this or delete this line to disable this function
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
}
This should work in both runtimes. The function wouldn't show in the azure portal.
I used the [Disable("myAppSetting")], but it did not disable my function at first. Turns out the app settings from the App Config Azure resource do not have an impact on this behavior. It needs to be put directly in the app settings of the Azure Function itself for it to work. The Azure portal however does show correctly that the function is disabled.

local development azure functions 'HttpRequestMessage' does not contain a definition for 'GetQueryNameValuePairs'

I am having trouble running an azure function locally that works in the portal. I created a default C# Http trigger in Azure, then download the app content to run locally.
[5/22/18 9:03:21 PM] run.csx(8,23): error CS1061: 'HttpRequestMessage' does not contain a definition for 'GetQueryNameValuePairs' and no extension method 'GetQueryNameValuePairs' accepting a first argument of type 'HttpRequestMessage' could be found (are you missing a using directive or an assembly reference?)
[5/22/18 9:03:21 PM] run.csx(20,15): error CS1501: No overload for method 'CreateResponse' takes 2 arguments
The function works perfectly in the portal.
As #Mikhail has said, it's caused by the wrong functions core tools(CLI) version. The code you download works with v1 CLI(.Net Framework) while v2(you may have installed) is on .NET Core.
To install required CLI, follow CLI installation. If local OS(like MacOS) doesn't support v1 CLI we may turn to v2 CLI which can run cross-platform. With v2 CLI, v1 code created on portal can't be used, hence we need to create functions locally or change portal function app runtime to ~2 then create and download again.
Note that before we change the runtime, function app should be empty because functions created before depend on different runtime and usually will become invalid after the change.
To give a specific example of code that does work, the below would work in Functions v2:
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post",
Route = null)] HttpRequest req, ILogger log)
{
int id;
bool parsedId = int.TryParse(req.Query["id"], out id);
...
}

Events not tracked in App Center

I am trying new Visual Studio App Center platform for mobile apps. It gives me the crashes and the installed versions OK, so the app secret and SDK are configured OK.
But when I try to track custom Events, according to this tutorial I get "No events found" in the Mobile Center dashboard. I try with my app in release and debug mode, without results.
My code (Xamarin.Forms):
public MyClass()
{
InitializeComponent();
Analytics.SetEnabledAsync(true);
Analytics.TrackEvent("Video clicked", new Dictionary<string, string> {
{ "Category", "Music" },
{ "FileName", "favorite.avi"}
});
}
There is the constructor, so I am sure that these lines are executed.
MobileCenter.Start needs to be called before Analytics.TrackEvent or Analytics.SetEnabledAsync.
If you are using constructor, then you need to move MobileCenter.Start to constructor as well.
Your solution is working probably because you made that code execute later (and thus after MobileCenter.Start) with async but you don't need to do that (and you don't need to call SetEnabledAsync at all, it's true by default and persisted).
Solved. I need to execute the lines in an async method, not in the constructor.

Precompiled Azure Function Behaving Unexpectedly

MyLibrary.dll
public class Person
{
[JsonProperty("name")]
public string Name { get; set; }
public static async Task Save(Person person)
{
DocumentClient client = CreateDocumentClient();
await client.OpenAsync();
await client.CreateDocumentAsync(CreateDocumentCollectionUri(), person);
}
}
MyFunctionApp.dll
public class SimpleHttpTrigger
{
public static async Task Run(HttpRequestMessage req)
{
Person bob = new Person() { Name = "Bob" };
await Person.Save(bob);
}
}
MyLibrary depends on:
Newtonsoft.Json 10.0.2
Microsoft.Azure.Documents.Client 1.13.1
And MyFunctionApp depends on MyLibrary.
The issue observed in this example is that the JsonProperty attribute is ignored when SimpleHttpTrigger.Run is called by the Azure Function CLI. SimpleHttpTrigger behaves as expected when called directly from a console app.
The issue can be resolved by changing MyLibrary's dependencies to match the versions currently used by the Azure Functions CLI:
Newtonsoft.Json 9.0.1
Microsoft.Azure.Documents.Client 1.11.4
It appears that Azure Function CLI ignores libraries in MyFunctionApp/bin when it has its own version of the library (found in node_modules/azure-functions-cli/bin). In this small example it's fine to match the dependencies but it isn't feasible when MyFunctionApp has a much larger dependency.
Is my understanding of this behaviour correct?
Is there any way to specify which version of these libraries to use in precompiled functions? I believe that one could get this behaviour in scripted functions by putting the dependencies inside the function's bin folder.
Update
My assumptions about the cause of this behaviour appear to be incorrect.
The newer versions of the Newtonsoft.Json and Microsoft.Azure.Documents.Client assemblies are in fact loaded alongside the Azure Function CLI's automatically loaded assemblies.
Which makes me even more confused as SimpleHttpTrigger.Run still behaves differently when called directly from a console app than it does when called by the Azure function host.
Any ideas what's going on? Possibly something stupid on my part.
Update 2
It looks like two different versions of the Newtonsoft.Json are used, whichever way the assemblies are loaded:
MyLibrary uses Newtonsoft.Json 10.0.2 as intended, but its dependency, Microsoft.Azure.Documents.Client 1.13.1, uses Newtonsoft.Json 9.0.1
Which might explain the incompatibility of the JsonProperty attribute.
Possibly? Please help, I'm very confused!
Basically, you are correct about the diagnosis of the problem.
This is an open issue with Azure Functions.
I stumbled on this myself and sympathize with your frustration.
Until the issue is solved, you must use the same major version of all the dependencies you happen to share with the implementation of Azure Functions.
Here is the list of Azure Functions dependencies : https://github.com/Azure/azure-webjobs-sdk-script/blob/dev/src/WebJobs.Script/packages.config
Open issues to track:
https://github.com/Azure/azure-webjobs-sdk-script/issues/573
https://github.com/Azure/azure-webjobs-sdk-script/issues/1311

Resources