Azure Functions - Value cannot be null. (Parameter 'connectionString') - javascript

I was trying to setup simple Azure Function to read a XML stream and sync it back to the database. My plan was to use a Time Trigger to execute the function once per day.
Howerver, things are not looking great. I'm getting the following error, even if I don't use a database:
[Error] Executed 'Functions.<func-name>' (Failed, Id=<func-id>, Duration=1ms)Value cannot be null. (Parameter 'connectionString')
I'm currently trying to execute the following function:
module.exports = async function(context, req) {
context.res = {
body: "Success!"
};
};
Same result. I can't run it.
I've added a Connection String to the Configuration -> Connection Strings (I thought that I've missed that, based on the message).
My functions.json file looks like:
{
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 0 * * * *"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
I've also tried running a C# function - same result.
So, what have I missed?

Logging from Microsoft to it's finest.
AzureWebJobsStorage App Setting was missing.
Solution:
Create Storage account (or use existing one)
Go to your Function App's Configuration
Add AzureWebJobsStorage with a connection string to your Storage account (can be found at Storage Account Overview -> Access Keys)

In my case the error was Microsoft.Extensions.Configuration.AzureAppConfiguration value cannot be null: parameter (connectionString)
This happened because I has installed Microsoft.Extensions.Configuration.AzureAppConfiguration in my Function to DI the configuration into my main function. The Startup.cs line string cs = Environment.GetEnvironmentVariable("MyDifferentConnectionString"); was not able to find an environment variable for MyDifferentConnectionString, so this needed to be added to the Function config.
Go to App Configuration (or create one)
Access Keys (under Settings)
Copy Connection String
Go to your Function
Configuration (under Settings)
Add a new Application Settings with the name of your environment variable and paste the value
Save and restart your Function

Related

Exception: You do not have permission to call DriveApp.createFile

I created a custom script to be run from google sheets which I need to create a file. The script uses the following code excerpt:
/*
Custom function to call IEXAPI IEXkeystatearningsdate
#customfunction
*/
function IEXkeystatearningsdate(inputsymbol, stat, version) {
if (version == "Sandbox" || version == "sandbox")
var url="https://sandbox.iexapis.com/stable/stock/"+inputsymbol+"/stats/"+stat+"?token=xyz";
else
var url="https://cloud.iexapis.com/stable/stock/"+inputsymbol+"/stats/"+stat+"?token=xyz";
var response=UrlFetchApp.fetch(url); //Call REST API
var json=response.getContentText();
var data = JSON.parse(json); //Parse into JSON object
var d = new Date();
var n = d.toLocaleString();
var fn = "IEXkeystatearningsdate_" + n;
DriveApp.createFile(fn,inputsymbol, MimeType.CSV);
return (data);
}
However, I receive this message:
"Exception: You do not have permission to call DriveApp.createFile. Required permissions: https://www.googleapis.com/auth/drive (line 20)"
When I run this script directly from the script editor, I don't receive this message.
This is my manifest file:
{
"oauthScopes": [
"https://www.googleapis.com/auth/drive"
],
"timeZone": "America/Los_Angeles",
"dependencies": {
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
I do not use G-Suite. I only use google/sheets for my personal use. The OAuth FAQ says this call should be allowed for personal use. Can someone help me with what I need to do to get this to work?
From your error description I can assume that you are running your script on a simple onEdit trigger.
Simple onEdit trigger cannot access services that require authorization.
See restrictions.
For you it means that you can perform to DriveApp on simple trigger.
Solution:
Use an Installable trigger instead.
To do so:
Rename the function onEdit() to something else that is not a key word
Go on Edit -> Current project's triggers
Click on + to create a new trigger
Specify the funciton to run
Set Select event type to On edit
Custom functions cannot be used to call services that access personal data:
Unlike most other types of Apps Scripts, custom functions never ask users to authorize access to personal data. Consequently, they can only call services that do not have access to personal data
That, of course, includes DriveApp. And it also includes things like getOAuthToken() (it returns null when called via custom functions), so calling Drive API directly through UrlFetch cannot work either.
You should either install an onEdit trigger, as ziganotschka suggested, or call this function through a custom menu instead of a custom function, so that you're asked for authorization when trying to run it.
Reference:
Using Apps Script services

Get StdOut from RunCommand using Azure VM Javascript SDK

I'm using the Azure VM Javascript SDK in my Node.js webApp. I'm trying to use the RunCommand Function to run a custom script on my Azure virtual machines.
The problem I'm having is with obtaining the response from running the command which should contain the StdOut and StdErr strings.
If I run the command from the Azure CLI, Like the following:
az vm run-command invoke -g 'myResource' -n 'myVm' --command-id RunPowerShellScript --scripts 'Get-ChildItem -Name'
Then I am able to receive the response, e.g. (notice in the 'message' section there is a listing of the files returned from 'Get-ChildItem')
{
"value": [
{
"code": "ComponentStatus/StdOut/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "myTxtFile.txt\nscript12.ps1\nscript13.ps1\nscript14.ps1\nscript15.ps1\nscript16.ps1\nscript17.ps1\nscript18.ps1\nscript19.ps1\nscript20.ps1\nscript21.ps1\nscript22.ps1\nscript23.ps1\nscript24.ps1\nscript25.ps1\nscript26.ps1",
"time": null
},
{
"code": "ComponentStatus/StdErr/succeeded",
"displayStatus": "Provisioning succeeded",
"level": "Info",
"message": "",
"time": null
}
]
}
However, when I run this code from the javascript SDK I don't get any thing returned. Here is the code:
let usr = ...;
let pas = ...;
let subscriptionId = ...;
let client = null;
msRestAzure.loginWithUsernamePassword(usr, pas, function(err, credentials) {
if (err) return console.log(err);
client = new azureArmCompute.ComputeManagementClient(credentials, subscriptionId);
let param = {
commandId: 'RunPowerShellScript',
script: [
'echo $null >> myTxtFile.txt\n' +
'Get-ChildItem -Name\n'
]
};
client.virtualMachines.runCommand('myResource', 'myVm', param, function (err, result) {
console.log(err);
console.log(result);
})
});
and here is what is printed to the console:
null
{}
I know that the script is actually running because I tried, and was successfully able, to create a text file (myTxtFile.txt).
Anyone have any clues as to why I'm not getting anything in the result object?
Edit 1 (in response to #Itay):
Looking at the source, the callback is supposed to be a "ServiceCallback" of type "RunCommandResult". Here are the three function declarations for RunCommand.
Here's the declaration for the ServiceCallback interface.
So in my callback I was expecting there to be four returns "err" and "result" and "request" and "response" (I'm obviously leaving off the latter two). In my example I'm printing the error and result objects to the console, but the result object doesn't have anything in it...
I think the signature for the callback you defined is not as described by the documentation.
Looking at runCommand(string, string, RunCommandInput, ServiceCallback< RunCommandResult >), it seems that the callback should be accepting a RunCommandResult interface, which in turn, contains a property called Value which is an array of InstanceViewStatus interface instances that might hold the information you are looking for.
Hope it helps!

Elastic search and Firebase: Result limit change and weird query results

I have setup an elastic search instant, created a Firebase project and run flashlight on my localhost. When I query the Firebase database in the default path (search/request) I get 10 results created in the search/response path in my database instance on Firebase.
Can someone more experienced on this please explain:
How can I change the result limit to more than 10 results on Firebase?
(I tried tinkering with SearchQueue.jsusing the code in the bottom but i didn't manage to make it work.
Why the search results when the queries are performed without specifying index and type return the total number of entries on elastic server and therefore irrelevant results on Firebase?
I used postman for the ReST calls (PUT) on firebase and the JSON content was sent over to /search/request/
This json content worked in terms of results:
{ "index": "chatmessages", "type": "chat", "query": "georgebest"}
but this one did not:
{"query": "georgebest"}
Both returned a Status: 200 OK .
Let me add that using Sense and running the same query the results are totally correct. The issue occurs when flashlight is used.
Please note that I don't use any rules and I left the Firebase database open for testing purposes.
Let me know if any additional information is required..Thanks.
code snippet for 1):
SearchQueue.prototype = {
_process: function(snap) {
var dat = snap.val();
var key = snap.key;
if (this._assertValidSearch(key, dat)) {
// Perform (a very simple) ElasticSearch query
var searchProps = {
index: dat.index,
type: dat.type,
//added variables
size : dat.size,
from : dat.from
};
It looks like you were running into a bug fixed in the 0.2.0 release.
Note that in the latest release query was replaced by q or body to be inline with ES. (query still works for now)
A more useful sample is now included in the doc here.
{
"from" : 0,
"size" : 50,
"body": {
"query": {
"match": {
"_all": "foo"
}
}
}
}
Using q for the sql lite format also works:
{
"from" : 0,
"size" : 50,
"q": "foo"
}
I found out what was causing the issues in my case (probably also caused via some other means as Kato suggested above).
For the first issue:
I was running a previous version of node.js in my system and what I did was to update the node.js to version 6.9.1 and then upgrade npm to version 4.0.2 (using npm install npm#latest -g ) afterwards I reinstated all the required node_modules (npm install --save firebase and npm install --save elasticsearch) and voila! it worked!
The code I used for the size and from variables:
SearchQueue.prototype = {
_process: function(snap) {
var dat = snap.val();
var key = snap.key;
if (this._assertValidSearch(key, dat)) {
// Perform (a very simple) ElasticSearch query
var searchProps = {
index: dat.index,
type: dat.type,
//added variables
size : dat.size,
from : dat.from,
};
The content of the json file :
{ "index":"chatmessages","type" : "chat", "query":"some_query", "from":"0", "size":"20"}
For the second issue:
The results were not passing correctly to elastic server, returning "undefined" and a hit number of all results stored.
I used postman to send the JSON in the following URL firebase_address/search/request/some_object.json
but just for reference if you want to do it manually in firebase, you should create something like this:
Of course the way to go from here is with the latest version as suggested above!

when I try to use find inside loopback model js file.iam getting error as Error: Cannot call user.find(). The find method has not been setup

Error: Cannot call user.find(). The find method has not been setup. The PersistedModel has not been correctly attached to a DataSource!
user.js is inside server/models/user.js
module.exports = function(User) {
User.find({where: {id:'3'}}, function(err,data) {
console.log(err);
console.log(data);
});
};
Your current model-config.json file has this line:
"user": { "dataSource": "db" }
Make the U capital in user as this is creating a new model user with lowercase letter and i think you haven't created its model files like user.js and user.json. It looks like you want to extend the built-in User model, in that case you can use this lowercase user model but keep both the model definitions in the model-config.js and use User as base in user.json file. Check Docs there is clear explanation for this
This is nothing to do with the "user" having a lowercase "u". Following the StrongLoop documentation, it looks like you've generated a model but not linked it to a data source.
In the documentation, it advises you to create a model and then change the datasource afterward. When you generate your model, the storage that is available for you to set will only be "db", which is an in-memory provider.
To get your API path to work correctly, firstly generate your model using:
slc loopback:model
Once you have generated your model, then run:
slc loopback:datasource
Which will then prompt you to fill in some options about your data source. Here's an example using MongoDB (note, where there is no data after the ':' is where you press enter to use the default value):
? Enter the data-source name: name_i_want_to_use_for_this
? Select the connector for name_i_want_to_use_for_this: MongoDB (supported by StrongLoop)
Connector-specific configuration:
? Connection String url to override other settings (eg: mongodb://username:password#hostname:port/database):
? host: localhost
? port:
? user:
? password:
? database: mydbname
? Install loopback-connector-mongodb#^1.4 Yes
This will then provide you with a connection provider called name_i_want_to_use_for_this. Now go into your /server/model-config.json and then scroll down to the name of your model and you will see:
"name_of_my_model": {
"dataSource": "db",
"public": true
}
Change this to:
"name_of_my_model": {
"dataSource": "name_i_want_to_use_for_this",
"public": true
}
Now you're done, go back into your strongloop project directory and run node ., and browse to http://localhost:3000/explorer. Go to the method you wanted to test, and test it in the explorer again, and it should now insert the data into the model.
To test this has worked, create a new record using the explorer, and then query its ID using the explorer.

chrome.storage.managed doesn't seem to work in my kiosk app

I've written a fairly simple kiosk app for a enterprise-enrolled/managed chromebox. I want to provide a default URL through a policy with chrome.storage.managed.
According to the documentation available a schema could look something like this:
{
"type": "object",
"properties": {
"DefaultUrl": {
"title": "Default URL",
"description": "The Default URL that will be loaded",
"type": "string"
}
}
}
And then the configuration text file you upload on the admin.google page would look like this (but this is kind of a guess):
{
"DefaultUrl": {
"Value": "http://example.com"
}
}
Next I try to use this URL using the following code:
chrome.storage.managed.get('DefaultUrl', function (data) {
var url = data.DefaultUrl;
/*if(url == undefined)
url = "undefined url";*/
//further code to proces the url
});
As far as I understand from the documentation a dict object with key/value pairs is returned containing the specified keys (1 in my case). When I uncomment the ifstatement in the above code the variable url always ends up being "undefined url", and otherwise it doesn't show any text (since it seems to be undefined)..
Debugging this isn't easy, because as far as I know you can't use console.log in kiosk mode, the policies can't be set through the admin panel when running it locally and since it's a managed device I can't run it from dev mode..
Can anyone tell me what's wrong here? If this is insufficient info I'd be glad to supply more, but my guess is the error is somewhere in the code above.
Update
I got this working locally when adding policies for chrome in my windows register, as described by the 'windows' part on: this site..
Allthough I am now using more than 1 policy, so maybe the error was that the schema expects atleast 2 policies? I have yet to test this on the kiosk app.

Categories