I am currently developing some C# Azure Functions. The naming convention I use is Process[ThingIWantToProcess]() like so...
public static void ProcessRequest([TimerTrigger("00:00:10", RunOnStartup = true, UseMonitor = false)] TimerInfo timer, ILogger logger)
{
// Do function things
}
A few days ago, all of the functions (currently, 6 of them) stopped running when they were deployed, but no code had been changed that I am aware of or can see.
The console, both locally and the Kudu console, say "Found the following functions:" and display all the expected functions; however, those functions are never run.
I tried all sorts of things, including re-deploys, restarting the Azure Web Job, and changing the contents of the methods, but still nothing fired. And then, I changed the name of the function, and suddenly it started working!
So instead of ProcessRequest it was now ProcessRequest1, and the function fired successfully. I changed the name several different ways, and all of them worked, but when I changed back to ProcessRequest, it stopped working again.
I can't find anything explaining this behavior in the docs or internet search, and I'm concerned it will happen again during future maintenance.
Has anyone else experienced this, and if so, can you point me to some kind of explanation?
Heyy !! This is due to the lock behavior that TimerTrigger employs to ensure that only a single instance of your function is running across scaled out instances. So if you are using the same Storage Account for multiple web job's you will face this issue.
To resolve this issue I would suggest just create separate Storage Account for you Job and it should work as it is !!!
For more information please visit: https://github.com/Azure/azure-webjobs-sdk/issues/614
No, it does not matter.
The FunctionName attribute marks the method as a function entry point. The name must be unique within a project, start with a letter and only contain letters, numbers, _, and -, up to 127 characters in length. Project templates often create a method named Run, but the method name can be any valid C# method name.
https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#methods-recognized-as-functions
Seems you are bit confused about is there any azure function naming convention? Okay let's make it more clear.
Azure Functions Are Like C# Method:
As you know Azure functions are like C# method. So it is good to follow C# method naming convention here also.
But azure functions Suggested Pattern like this <name>-func
Example azureexample-func
public static class AzureFunctionExampleClass
{
[FunctionName("azureexample-func")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
//Read Request Body
var content = await new StreamReader(req.Body).ReadToEndAsync();
//Extract Request Body and Parse To Class
Users objUsers = JsonConvert.DeserializeObject<Users>(content);
//As we have to return IAction Type So converting to IAction Class Using OkObjectResult We Even Can Use OkResult
var result = new OkObjectResult(objUsers);
return (IActionResult)result;
}
}
Note: You even can use PascalCase format like AzureExampleFunc. As there is no such strict bindings.
Casing:
Case insensitive
Function Valid Characters: Alphanumeric and hyphen
Function Length:
1-60
Key-Words Should Skip:
Every language has its own defined key-words while name your function its good to omit that name. So that compiler never get confused about that.
Make Function Readable:
Though function doesn't restricts any mandatory naming convention but its recommended to use a readable name so that its be easy to understand what it does.
If you still have any query regarding Azure naming convention you could check this docs
Thank you and happy coding!
Related
I have a C# WebJob that uses QueueTrigger with a custom INameResolver to look up queue names from the application settings. This part is working as expected, but now within the method body, I need to know the name of the queue from which the triggering message was received. Ideally, I'd like to just be able to add a specially-named string parameter on my method which would be populated with the triggering queue name by the WebJobs SDK, but the documentation doesn't mention any such bindable parameter.
Is there another way to accomplish this, preferrably without hardcoding the queue name/pattern in two locations (i.e. once in the QueueTrigger attribute and again inside the method body) or writing custom string-parsing code to manually invoke my INameResolver for %patterns%?
You could add an additional parameter to your function to bind to the queue like so:
public static void MyFunction(
[QueueTrigger("%name%")] string message,
[Queue("%name%")] CloudQueue queue)
{
string queueName = queue.Name;
}
An alternative is as you suggested - make your custom INameResolver instance available to your job function (e.g. via DI) and just call resolver.Resolve to get the name.
Thanks in advance for the help -
I am new to mockito but have spent the last day looking at examples and the documentation but haven't been able to find a solution to my problem, so hopefully this is not too dumb of a question.
I want to verify that deleteLogs() calls deleteLog(Path) NUM_LOGS_TO_DELETE number of times, per path marked for delete. I don't care what the path is in the mock (since I don't want to go to the file system, cluster, etc. for the test) so I verify that deleteLog was called NUM_LOGS_TO_DELETE times with any non-null Path as a parameter. When I step through the execution however, deleteLog gets passed a null argument - this results in a NullPointerException (based on the behavior of the code I inherited).
Maybe I am doing something wrong, but verify and the use of isNotNull seems pretty straight forward...here is my code:
MonitoringController mockController = mock(MonitoringController.class);
// Call the function whose behavior I want to verify
mockController.deleteLogs();
// Verify that mockController called deleteLog the appropriate number of times
verify(mockController, Mockito.times(NUM_LOGS_TO_DELETE)).deleteLog(isNotNull(Path.class));
Thanks again
I've never used isNotNull for arguments so I can't really say what's going wrong with you code - I always use an ArgumentCaptor. Basically you tell it what type of arguments to look for, it captures them, and then after the call you can assert the values you were looking for. Give the below code a try:
ArgumentCaptor<Path> pathCaptor = ArgumentCaptor.forClass(Path.class);
verify(mockController, Mockito.times(NUM_LOGS_TO_DELETE)).deleteLog(pathCaptor.capture());
for (Path path : pathCaptor.getAllValues()) {
assertNotNull(path);
}
As it turns out, isNotNull is a method that returns null, and that's deliberate. Mockito matchers work via side effects, so it's more-or-less expected for all matchers to return dummy values like null or 0 and instead record their expectations on a stack within the Mockito framework.
The unexpected part of this is that your MonitoringController.deleteLog is actually calling your code, rather than calling Mockito's verification code. Typically this happens because deleteLog is final: Mockito works through subclasses (actually dynamic proxies), and because final prohibits subclassing, the compiler basically skips the virtual method lookup and inlines a call directly to the implementation instead of Mockito's mock. Double-check that methods you're trying to stub or verify are not final, because you're counting on them not behaving as final in your test.
It's almost never correct to call a method on a mock directly in your test; if this is a MonitoringControllerTest, you should be using a real MonitoringController and mocking its dependencies. I hope your mockController.deleteLogs() is just meant to stand in for your actual test code, where you exercise some other component that depends on and interacts with MonitoringController.
Most tests don't need mocking at all. Let's say you have this class:
class MonitoringController {
private List<Log> logs = new ArrayList<>();
public void deleteLogs() {
logs.clear();
}
public int getLogCount() {
return logs.size();
}
}
Then this would be a valid test that doesn't use Mockito:
#Test public void deleteLogsShouldReturnZeroLogCount() {
MonitoringController controllerUnderTest = new MonitoringController();
controllerUnderTest.logSomeStuff(); // presumably you've tested elsewhere
// that this works
controllerUnderTest.deleteLogs();
assertEquals(0, controllerUnderTest.getLogCount());
}
But your monitoring controller could also look like this:
class MonitoringController {
private final LogRepository logRepository;
public MonitoringController(LogRepository logRepository) {
// By passing in your dependency, you have made the creator of your class
// responsible. This is called "Inversion-of-Control" (IoC), and is a key
// tenet of dependency injection.
this.logRepository = logRepository;
}
public void deleteLogs() {
logRepository.delete(RecordMatcher.ALL);
}
public int getLogCount() {
return logRepository.count(RecordMatcher.ALL);
}
}
Suddenly it may not be so easy to test your code, because it doesn't keep state of its own. To use the same test as the above one, you would need a working LogRepository. You could write a FakeLogRepository that keeps things in memory, which is a great strategy, or you could use Mockito to make a mock for you:
#Test public void deleteLogsShouldCallRepositoryDelete() {
LogRepository mockLogRepository = Mockito.mock(LogRepository.class);
MonitoringController controllerUnderTest =
new MonitoringController(mockLogRepository);
controllerUnderTest.deleteLogs();
// Now you can check that your REAL MonitoringController calls
// the right method on your MOCK dependency.
Mockito.verify(mockLogRepository).delete(Mockito.eq(RecordMatcher.ALL));
}
This shows some of the benefits and limitations of Mockito:
You don't need the implementation to keep state any more. You don't even need getLogCount to exist.
You can also skip creating the logs, because you're testing the interaction, not the state.
You're more tightly-bound to the implementation of MonitoringController: You can't simply test that it's holding to its general contract.
Mockito can stub individual interactions, but getting them consistent is hard. If you want your LogRepository.count to return 2 until you call delete, then return 0, that would be difficult to express in Mockito. This is why it may make sense to write fake implementations to represent stateful objects and leave Mockito mocks for stateless service interfaces.
In my plugin code, I use early bound entities (generated via the crmsvcutil). Within my code, I am using MemberExpression to retrieve the name of the property. For instance, if I want the full name of the user who initiated the plugin I do the following
SystemUser pluginExecutedBy = new SystemUser();
pluginExecutedBy = Common.RetrieveEntity(service
, SystemUser.EntityLogicalName
, new ColumnSet(new string[] {Common.GetPropertyName(() => pluginExecutedBy.FullName)})
, localContext.PluginExecutionContext.InitiatingUserId).ToEntity<SystemUser>();
The code for GetPropertyName is as follows
public static string GetPropertyName<T>(Expression<Func<T>> expression)
{
MemberExpression body = (MemberExpression)expression.Body;
return body.Member.Name.ToLower();
}
The code for RetrieveEntity is as follows
public static Entity RetrieveEntity(IOrganizationService xrmService, string entityName, ColumnSet columns, Guid entityId)
{
return (Entity)xrmService.Retrieve(entityName, entityId, columns);
}
My solution architect's comments:
Instead of writing the code like above, why not write it like this (hardcoding the name of the field - or use a struct).
SystemUser pluginExecutedBy = null;
pluginExecutedBy = Common.RetrieveEntity(service
, SystemUser.EntityLogicalName
, new ColumnSet(new string[] {"fullname"})
, localContext.PluginExecutionContext.InitiatingUserId).ToEntity<SystemUser>();
Reason:
Your code unnecessarily creates an object before it requires it (as you instantiate the object with the new keyword before the RetrieveEntity in order to use it with my GetProperty method) which is bad programming practice. In my code, I have never used the new keyword, but merely casting it and casting does not create a new object. Now, I am no expert in C# or .NET, but I like to read and try out different things. So, I looked up the Microsoft.Xrm.Sdk.dll and found that ToEntity within Sdk, actually did create a new Entity using the keyword new.
If the Common.Retrieve returns null, your code has unnecessarily allocated memory which will cause performance issues whereas mine would not?
A managed language like C# "manages the memory" for me, does it not?
Question
Is my code badly written? If so, why? If it is better - why is it? (I believe it is a lot more cleaner and even if a field name changes as long as as the early bound class file is regenerated, I do not have to re-write any code)
I agree that cast does not create a new object, but does my code unnecessarily create objects?
Is there a better way (a completely different third way) to write the code?
Note: I suggested using the GetPropertyName because, he was hard-coding attribute names all over his code and so in a different project which did not use early bound entities I used structs for attribute names - something like below. I did this 3 weeks into my new job with CRM 2011 but later on discovered the magic of MemberExpression. He was writing a massive cs file for each of the entity that he was using in his plugin and I told him he did not have to do any of this as he could just use my GetPropertyName method in his plugin and get all the fields required and that prompted this code review comments. Normally he does not do a code review.
public class ClientName
{
public struct EntityNameA
{
public const string LogicalName = "new_EntityNameA";
public struct Attributes
{
public const string Name = "new_name";
public const string Status = "new_status";
}
}
}
PS: Or is the question / time spent analyzing just not worth it?
Early Bound, Late Bound, MemberExpression, bla bla bla :)
I can understand the "philosophy", but looking at your code a giant alarm popup in my head:
public static Entity RetrieveEntity(IOrganizationService xrmService, string entityName, ColumnSet columns, Guid entityId)
{
return (Entity)xrmService.Retrieve(entityName, entityId, columns);
}
the Retrieve throws an exception if the record is not found.
About the other things, the GetPropertyName is ok, but are always choices, for example I try to use always late bound in plugins, maybe in a project I prefer to use early bound, often there is more than one way to resolve a problem.
Happy crm coding!
Although GetPropertyName is a quite a clever solution I don't like it, and that's entirely to do with readability. To me its far easier to understand what is going on with: new ColumnSet(new string[] {"fullname"}).
But that's pretty much personal preference, but its important to remember that your not just writing code for yourself you are writing it for your team, they should be able to easily understand the work you have produced.
As a side a hardcoded string probably performs better at runtime. I usually hardcode all my values, if the entity model in CRM changes I will have to revisit to make changes in any case. There's no difference between early and late bound in that situation.
I don't understand the point of this function,
public static Entity RetrieveEntity(IOrganizationService xrmService, string entityName, ColumnSet columns, Guid entityId)
{
return (Entity)xrmService.Retrieve(entityName, entityId, columns);
}
It doesn't do anything (apart from cast something that is already of that type).
1.Your code unnecessarily creates an object before it requires it (as you instantiate the object with the new keyword before the
RetrieveEntity in order to use it with my GetProperty method) which is
bad programming practice. In my code, I have never used the new
keyword, but merely casting it and casting does not create a new
object.
I believe this refers to; SystemUser pluginExecutedBy = new SystemUser(); I can see his/her point here, in this case new SystemUser() doesn't do much, but if the object you were instantiating did something resource intensive (load files, open DB connections) you might be doing something 'wasteful'. In this case I would be surprised if changing SystemUser pluginExecutedBy = null; actually yielded any significant performance gain.
2.If the Common.Retrieve returns null, your code has unnecessarily allocated memory which will cause performance issues
I would be surprised if that caused a performance issue, and anyway as Guido points out that function wont return null in any case.
Overall there is little about this code I strongly feel needs changing - but things can be always be better and its worth discussing (e.g. the point of code review), although it can be hard not to you shouldn't be precious about your code.
Personally I would go with hardcoded attribute names and dump the Common.RetrieveEntity function as it doesn't do anything.
pluginExecutedBy = service.Retrieve(SystemUser.EntityLogicalName, localContext.PluginExecutionContext.InitiatingUserId, new ColumnSet(new String[] {"fullname"} ));
I am trying to write a method to create a database and run migrations on it, given the connection string.
I need the multiple connections because I record an audit log in a separate database.
I get the connection strings out of app.config using code like
ConfigurationManager.ConnectionStrings["Master"].ConnectionString;
The code works with the first connection string defined in my app.config but not others, which leads me to think that somehow it is getting the connection string from app.config in some manner I don't know.
My code to create the database if it does not exist is
private static Context MyCreateContext(string ConnectionString)
{
// put the connection string where the factory method can get it
AppDomain.CurrentDomain.SetData("ConnectionString", ConnectionString );
var factory = new ContextFactory();
// I know I need this line - but I cant see how what follows actually uses it
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context,DataLayer.Migrations.Configuration>());
var context = factory.Create();
context.Database.CreateIfNotExists();
return context
}
The code in the Migrations.Configuration is
Public sealed class Configuration : DbMigrationsConfiguration<DataLayer.Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
}
The context factory code is
public class ContextFactory : IDbContextFactory<Context>
{
public Context Create()
{
var s = (string)AppDomain.CurrentDomain.GetData("ConnectionString");
return new Context(s);
}
}
Thus I am setting the connection string before creating the context.
Where can I be going wrong, given that the connection strings are all the same except the database name, and the migration code runs with one connection string, but doesnt run with others?
I wonder if my problem is to do with understanding how How does Database.SetInitializer actually works. I am guessing something about reflection or generics. How do i make the call to SetInitializer tie tie to my actual context?
I have tried the following code but the migrations do not run
private static Context MyCreateContext(string ConnectionString)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, DataLayer.Migrations.Configuration>());
var context = new Context(ConnectionString);
context.Database.CreateIfNotExists();
}
This question appears to be related
UPDATE:
I can get the migrations working if I refer to the connection string using
public MyContext() : base("MyContextConnection") - which points to in the config
I was also able to get migrations working on using different instances of the context, if I created a ContextFactory class and passed the connection to it by referencing a global. ( See my answer to the related question link )
Now I am wondering why it has to be so hard.
I'm not sure exactly as to what the problems are you facing, but let me try
The easiest way to provide connection - and be sure it works that way...
1) Use your 'DbContext' class name - and define a connection in the app.config (or web.config). That's easiest, you should have a connection there that matches your context class name,
2) If you put it into the DbContext via constructor - then be consistent and use that one. I'd also suggest to 'read' from config connections - and again name it 'the same' as your context class (use the connection 'name', not the actual string),
3) if none is present - EF/CF makes the 'default' one - based on your provider - and your context's class name - which usually isn't what you want,
You shouldn't customize with initializers for that reason -
initializers should be agnostic and serve other purpose - setup
connection in the .config - or directly on your DbContext
Also check this Entity Framework Code First - How do I tell my app to NOW use the production database once development is complete instead of creating a local db?
Always check 'where your data' goes - before doing anything.
For how the initializer actually works - check this other post of mine, I made a thorough example
How to create initializer to create and migrate mysql database?
Notes: (from the comments)
Connection shouldn't be very dynamic - config is the right place for it to be, unless you have a good reason.
Constructor should work fine too.
CreateDbIfNotExists doesn't work well together with the 'migration' initializer. You can just use the MigrateDatabaseToLatestVersion initializer. Don't 'mix' it
Or - put something like public MyContext() : base("MyContextConnection") - which points to <connectionStrings> in the config
To point to connection - just use its 'name' and put that into constructor.
Or use somehting like ConfigurationManager.ConnectionStrings["CommentsContext"].ConnectionString
Regarding entertaining 'multiple databases' with migrations (local and remote from one app) - not exactly related - but this link - Migration not working as I wish... Asp.net EntityFramework
Update:
(further discussion here - Is adding a class that inherits from something a violation of the solid principles if it changes the behavior of code?)
It is getting interesting here. I did manage to reproduce the problems you're facing actually. Here is a short breakdown on what I think it's happening:
First, this worked 'happily':
Database.SetInitializer(new CreateAndMigrateDatabaseInitializer<MyContext, MyProject.Migrations.Configuration>());
for (var flip = false; true; flip = !flip)
{
using (var db = new MyContext(flip ? "Name=MyContext" : "Name=OtherContext"))
{
// insert some records...
db.SaveChanges();
}
}
(I used custom initializer from my other post, which controls migration/creation 'manually')
That worked fine w/o an Initializer. Once I switched that on, I ran into some curious problems.
I deleted Db-s (two, for each connection). I expected to either not work, or create one db, then another in the next pass (like it did, w/o migrations, just 'Create' initializer).
What happened, to my surprise - is it actually created both databases on the first
pass ??
Then, being a curious person:), I put breakpoints on the MyContext ctor, and debugged through the migrator/initializer. Again empty/no db-s etc.
It created first instance on my call within the flip. Then on the first access to 'model', it invoked the initializer. Migrator took over (having had no db-s). During the migrator.Update(); it actually constructs the MyContext (I'm guessing via generic param in Configuration) - and calls the 'default' empty ctor. That had the 'other connection/name' by default - and creates the other Db all as well.
So, I think this explains what you're experiencing. And why you had to create the 'Factory' to support the Context creation. That seems to be the only way. And setting some 'AppDomain' wide 'connection string' (which you did well actually) which isn't 'overriden' by default ctor call.
Solution that I see is - you just need to run everything through factory - and 'flip' connections in there (no need for static connection, as long as your factory is a singleton.
You can supply a configuration in the MigrateDatabaseToLatestVersion constructor.
If you set the initializer in the DbContext you can also pass a 'true' to use the current connection string.
Trying to push a message into UI and receive some result to return in synchronous way from web-service.
Method code goes as follows.
[OperationContract]
public string DecypherCaptcha(string captcha)
{
var connection = new HubConnection("http://localhost:51806");
IHubProxy hub = connection.CreateHubProxy("robo");
string decaptcha = null;
hub.On("captchaDecyphered", decyphered =>
{
decaptcha = decyphered;
});
connection.Start().Wait();
hub.Invoke<string>("DecypherCaptcha", new object[] { captcha });
return decaptcha;
}
The issue is that method finishes before value is obtained from hub's captchaDecyphered. However the expression { decaptcha = decyphered; } triggers fine from server after method exits.
Adding ManualResetEvent flag and WaitOne() for it doesn't solve the problem freezing the execution and preventing hub.On("captchaDecyphered" from firing.
Any ideas how to synchronize this?
UPDATE#1 Small notice. Cannot avoid using the intermediate synchronous WCF web-service acting as SignalR client, because of pretty specific robots sitting behind, which are able to interact with outer world only by calling webservices synchronously. Basically in this scenario when robot faces captcha it calls the web-service passing it via SignalR to UI for manual recognition.
UPDATE#2 Thanks to #Ken's inspiring advice got it working by enclosing the connection establishing and hub method invocation into separate 'Thread' followed by waiting with 'ManualResetEvent':
new Thread(() =>
{
connection.Start().Wait();
hub.Invoke<string>("DecypherCaptcha", new object[] { captcha });
}).Start();
sync.WaitOne();
Have previously been trying to start from 'Task' supposing it would run on separate thread implicitly, but with no luck.
You could have the DecypherCaptcha hub method on the SignalR server return the deciphered captcha as a Task<string> instead on invoking captchaDecyphered.
You may want to use a TaskCompletionSource to help you create the appropriate task. Basically you could call tcs.SetResult(deciphered) and return tcs.Task instead of calling Clients.Caller.captchaDecyphered(deciphered).
Then your client-side code code would simply be:
[OperationContract]
public string DecypherCaptcha(string captcha)
{
var connection = new HubConnection("http://localhost:51806");
IHubProxy hub = connection.CreateHubProxy("robo");
connection.Start().Wait();
return hub.Invoke<string>("DecypherCaptcha", captcha).Result;
}
You've got several options.
(1) Spin off the request to the SignalR hub onto a separate thread, probably using the static ThreadPool class, and then add in all the ManualResetEvent stuff. That way it won't block when you're waiting on the SignalR method to return.
(2) Make the DecypherCaptcha method asynchronous. It looks to me like the DecypherCaptcha() is intended to be a WCF method that in turn wraps a SignalR method. If that's the case, forgetting for a moment whether this is a wise approach, you could still call a WCF method on the client when the captchaDecyphered SignalR method completes. But if it's not intended to be a WCF method, then you could have DecypherCaptcha() either (a) return a Task<T>, and only flag the Task to be complete when the captchaDecyphered completes; or (b) pass in a Func<T> as a continuation parameter, and call that when the captchaDecyphered completes.
In general, one of the things that makes asynchronous programming difficult is that except for the very top-level method, you generally need to make every method that calls an asynchronous method itself asynchronous, all the way up and down the stack, either through the Async pattern (nasty), or continuation passing (better) or through a Task object + async/await (probably best). So adding in a single asynchronous method often results in significant changes to your application, all the way through. That's one of the many reasons why the new async and await keywords in .NET 4.5 are so helpful, because they help to encapsulate the necessary changes when you start making your application asynchronous.
You can use the generic Invoke method where you can specify the type of result you expect. With the method you CAN use .Result to wait for the result.
string result = IHubProxy.Invoke<string>("GetString").Result;