Is there a way to specifically create an Application Insights using Azure Fluent API?
I see there is a Monitor code sample, but this is not specific to Application Insights.
EDIT:
After trying the Azure SDK API from here, I got an error not identified in their documentation.
Currently Fluent API does not support for Application Insights.
It appears the .NET Fluent Azure libraries do not support Application
Insight provisioning while the Java SDK does
Same with C# too.
According to Azure SDK API, there is no Application Insight management API currently.
But we could create the Application Insights with following API. For more information, please refer to this.
You could test it directly with [try it].
PUT https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Insights/components/{resourceName}?api-version=2015-05-01
This is an old topic, but apparently Application Insights still isn't part of the Azure Management API yet. I created a class for this, which works a bit like the Fluent API would.
public class AppInsights
{
public IAzureRestClient azureRestClient { get; private set; }
public AppInsights(IAzureRestClient client)
{
this.azureRestClient = client;
}
public Dictionary<string, string> Tags { get; private set; }
public AppInsights WithTags(Dictionary<string, string> tags)
{
this.Tags = tags;
return this;
}
public string Name { get; private set; }
public AppInsights WithName(string name)
{
this.Name = name;
return this;
}
public string SubscriptionId { get; private set; }
public AppInsights WithSubscriptionId(string id)
{
this.SubscriptionId = id;
return this;
}
public IResourceGroup ResourceGroup { get; private set; }
public AppInsights WithResourceGroup(IResourceGroup group)
{
this.ResourceGroup = group;
return this;
}
public string AssociatedApp { get; private set; }
public AppInsights WithAssociatedApp(string appName)
{
this.AssociatedApp = appName;
return this;
}
public AppInsightsComponent Create()
{
// initialize tags
var tags = new Dictionary<string, string>(Tags);
if (!string.IsNullOrWhiteSpace(AssociatedApp))
{
// Add a tag to associate the App Insights instance with the app service
// ARM syntax for this: "[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', parameters('webSiteName'))]": "Resource",
tags.Add($"hidden-link:{ResourceGroup.Id}/providers/Microsoft.Web/sites/{Name}-portal", "Resource");
}
// Create the resource
var url = $"https://management.azure.com/subscriptions/{SubscriptionId}/resourceGroups/{ResourceGroup.Name}/providers/Microsoft.Insights/components/{Name}?api-version=2015-05-01";
dynamic reqBody = new JObject();
reqBody.Location = ResourceGroup.RegionName;
reqBody.Kind = "web";
reqBody.tags = JObject.FromObject(tags);
dynamic properties = new JObject();
properties.ApplicationType = "web";
properties.FlowType = "Bluefield";
properties.RequestSource = "rest";
reqBody.Properties = properties;
var response = azureRestClient.Put(url, reqBody);
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException($"management.azure.com returned {response.StatusCode.ToString()}");
}
var responseBody = response.Content.ReadAsStringAsync().Result;
return Newtonsoft.Json.JsonConvert.DeserializeObject<AppInsightsComponent>(responseBody);
}
There's more context on this github page.
Related
We have a SharePoint list that contains a large PDF attachment and have set up an Azure Webhook to notify an Azure Function App of a change to the SharePoint list and would like to have the ability to check for and parse a PDF attachment.
I am fairly still new to this type of development, but have found an example that I followed, and our test currently seems to be triggering an event in our Azure Function and can see that the trigger is successful:
Monitor Invocation:
The code that I've implemented is pretty much verbatim from the above link example and it appears that most of the functionality is currently simply writing out log information, however I've not been able to find many examples of detailed implementation scenarios using SharePoint Lists to get an attachment from a SharePoint List.
Should we be getting our attachment data after reading in the request into a StreamReader object here?
var content = await new StreamReader(req.Body).ReadToEndAsync();
Full Code Context:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req,
ICollector<string> outputQueueItem, ILogger log)
{
log.LogInformation($"Webhook was triggered!");
// Grab the validationToken URL parameter
string validationToken = req.Query["validationtoken"];
// If a validation token is present, we need to respond within 5 seconds by
// returning the given validation token. This only happens when a new
// webhook is being added
if (validationToken != null)
{
log.LogInformation($"Validation token {validationToken} received");
return (ActionResult)new OkObjectResult(validationToken);
}
log.LogInformation($"SharePoint triggered our webhook...great :-)");
//Is the attachment available via the content variable?
var content = await new StreamReader(req.Body).ReadToEndAsync();
log.LogInformation($"Received following payload: {content}");
var notifications = JsonConvert.DeserializeObject<ResponseModel<NotificationModel>>(content).Value;
log.LogInformation($"Found {notifications.Count} notifications");
if (notifications.Count > 0)
{
log.LogInformation($"Processing notifications...");
foreach(var notification in notifications)
{
// add message to the queue
string message = JsonConvert.SerializeObject(notification);
log.LogInformation($"Before adding a message to the queue. Message content: {message}");
outputQueueItem.Add(message);
log.LogInformation($"Message added :-)");
}
}
// if we get here we assume the request was well received
return (ActionResult)new OkObjectResult($"Added to queue");
}
// supporting classes
public class ResponseModel<T>
{
[JsonProperty(PropertyName = "value")]
public List<T> Value { get; set; }
}
public class NotificationModel
{
[JsonProperty(PropertyName = "subscriptionId")]
public string SubscriptionId { get; set; }
[JsonProperty(PropertyName = "clientState")]
public string ClientState { get; set; }
[JsonProperty(PropertyName = "expirationDateTime")]
public DateTime ExpirationDateTime { get; set; }
[JsonProperty(PropertyName = "resource")]
public string Resource { get; set; }
[JsonProperty(PropertyName = "tenantId")]
public string TenantId { get; set; }
[JsonProperty(PropertyName = "siteUrl")]
public string SiteUrl { get; set; }
[JsonProperty(PropertyName = "webId")]
public string WebId { get; set; }
}
public class SubscriptionModel
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Id { get; set; }
[JsonProperty(PropertyName = "clientState", NullValueHandling = NullValueHandling.Ignore)]
public string ClientState { get; set; }
[JsonProperty(PropertyName = "expirationDateTime")]
public DateTime ExpirationDateTime { get; set; }
[JsonProperty(PropertyName = "notificationUrl")]
public string NotificationUrl {get;set;}
[JsonProperty(PropertyName = "resource", NullValueHandling = NullValueHandling.Ignore)]
public string Resource { get; set; }
}
I thought that I would try to debug this integration remotely since the code is running in the Azure Portal in order to set up watches and look into the HTTPRequest and StreamReader objects, however that's presented a whole new set of challenges and we've been unsuccessful there as well.
Thanks in advance.
What you've done here is fine, assuming you end up with an item placed on a queue. The real heavy lifting though will happen with the function that picks up the item off the queue. The json you send to the queue only notes that a change occurred; your queue receiver is going to have to authenticate and call back into SharePoint to fetch the data and do what it needs to do.
Read the reference implementation section of the documentation you linked for a better explanation of the webhooks architecture.
I will add that developing Azure functions directly in the portal is going to be a nightmare for anything but trivial applications. And your application is not trivial. The ngrok based approach in the Get Started section is good advice and really the only way to debug webhooks. Good luck!
Is it possible to connect to a Service Bus Topic using App Service Function App's MSI? Any documentations or examples to perform this via ARM Template or .NET SDK (C#) would be helpful.
See example below:
namespaces:
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Primitives;
Adding services to the container:
services.Configure<ServiceBusConfiguration>(Configuration.GetSection("ServiceBus"));
Main implementation:
public class ServiceBusConfiguration
{
public string Namespace { get; set; }
public string Topic { get; set; }
}
public class HomeController : Controller
{
public ServiceBusConfiguration Config { get; }
public HomeController(IOptions<ServiceBusConfiguration> serviceBusConfig)
{
Config = serviceBusConfig.Value;
}
[HttpPost]
public async Task<ActionResult> Send(ServiceBusMessageData messageInfo)
{
if (string.IsNullOrEmpty(messageInfo.MessageToSend))
{
return RedirectToAction("Index");
}
var tokenProvider = TokenProvider.CreateManagedServiceIdentityTokenProvider();
var sendClient = new TopicClient($"sb://{Config.Namespace}.servicebus.windows.net/", Config.Topic, tokenProvider);
await sendClient.SendAsync(new Message(Encoding.UTF8.GetBytes(messageInfo.MessageToSend)));
await sendClient.CloseAsync();
return RedirectToAction("Index");
}
}
To get more details please see Use Service Bus from App Service with Managed Service Identity
I'm developing an Azure Mobile App service to interface to my Xamarin application.
I've created, connected and successfully populated an SQL Database, but when I try to add some filters to my request, for example an orderby() or where() clauses, it returns me a Bad Request error.
For example, this request: https://myapp.azurewebsites.net/tables/Race?$orderby=iRound%20desc,iYear%20desc&$top=1&ZUMO-API-VERSION=2.0.0 gives me {"message":"The query specified in the URI is not valid. Could not find a property named 'IYear' on type 'MyType'."}.
My configuration method is this:
HttpConfiguration config = new HttpConfiguration();
new MobileAppConfiguration()
.AddTablesWithEntityFramework()
.ApplyTo(config);
config.MapHttpAttributeRoutes();
Database.SetInitializer(new CreateDatabaseIfNotExists<MainDataContext>());
app.UseWebApi(config);
and my DbContext is this:
public class MainDataContext : DbContext
{
private const string connectionStringName = "Name=MS_TableConnectionString";
public MainDataContext() : base(connectionStringName)
{
Database.Log = s => WriteLog(s);
}
public void WriteLog(string msg)
{
System.Diagnostics.Debug.WriteLine(msg);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(
new AttributeToColumnAnnotationConvention<TableColumnAttribute, string>(
"ServiceTableColumn", (property, attributes) => attributes.Single().ColumnType.ToString()));
}
public DbSet<Race> Race { get; set; }
public DbSet ...ecc...
}
Following this guide, I added a migration after creating my TableControllers. So the TableController for the example type shown above is pretty standard:
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
public class RaceController : TableController<Race>
{
protected override void Initialize(HttpControllerContext controllerContext)
{
base.Initialize(controllerContext);
MainDataContext context = new MainDataContext();
DomainManager = new EntityDomainManager<Race>(context, Request);
}
// GET tables/Race
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Race> GetAllRace()
{
return Query();
}
// GET tables/Race/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<Race> GetRace(string id)
{
return Lookup(id);
}
// PATCH tables/Race/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task<Race> PatchRace(string id, Delta<Race> patch)
{
return UpdateAsync(id, patch);
}
// POST tables/Race
public async Task<IHttpActionResult> PostRace(Race item)
{
Race current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
// DELETE tables/Race/48D68C86-6EA6-4C25-AA33-223FC9A27959
public Task DeleteRace(string id)
{
return DeleteAsync(id);
}
}
As you can see, I already tried to add the EnableQuery attribute to my TableController, as seen on Google. I also tried to add these filters to the HttpConfiguration object, without any success:
config.Filters.Add(new EnableQueryAttribute
{
PageSize = 10,
AllowedArithmeticOperators = AllowedArithmeticOperators.All,
AllowedFunctions = AllowedFunctions.All,
AllowedLogicalOperators = AllowedLogicalOperators.All,
AllowedQueryOptions = AllowedQueryOptions.All
});
config.AddODataQueryFilter(new EnableQueryAttribute
{
PageSize = 10,
AllowedArithmeticOperators = AllowedArithmeticOperators.All,
AllowedFunctions = AllowedFunctions.All,
AllowedLogicalOperators = AllowedLogicalOperators.All,
AllowedQueryOptions = AllowedQueryOptions.All
});
I don't know what to investigate more, as things seems to be changing too fast for a newbie like me who's first got into Azure.
EDIT
I forgot to say that asking for the complete table, so for example https://myapp.azurewebsites.net/tables/Race?ZUMO-API-VERSION=2.0.0, returns correctly the entire dataset. The problem occurs only when adding some clauses to the request.
EDIT 2
My model is like this:
public class Race : EntityData
{
public int iRaceId { get; set; }
public int iYear { get; set; }
public int iRound { get; set; }
ecc..
}
and the database table that was automatically created is this, including all the properties inherited from EntityData:
Database table schema
Digging into the source code, Azure Mobile Apps sets up camelCase encoding of all requests and responses. It then puts them back after transmission accordign to rules - so iRaceId becomes IRaceId on the server.
The easiest solution to this is to bypass the auto-naming and use a JsonProperty attribute on each property within your server-side DTO and client-side DTO so that they match and will get encoding/decoded according to your rules.
So:
public class Race : EntityData
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("raceId")]
public int iRaceId { get; set; }
[JsonProperty("year")]
public int iYear { get; set; }
[JsonProperty("round")]
public int iRound { get; set; }
etc..
}
I would like to write a web app that allows users to write C# scripts and execute them using Azure Functions.
I checked Azure SDK documentation and didn't find any nuget packages for managing Function Apps.
Is there a way I can:
retrieve list of available azure functions
deploy azure function
update azure function
delete azure function
using Azure SDK? If not, what would be another way to do it?
Update on Jul 8, 2019
I found List and Delete functions in Azure SDK (Microsoft.Azure.Management.WebSites):
List:
Msdn Documentation
Delete
Msdn Documentation
I tested them and they work.
The problem is with Create method _CreateFunctionWithHttpMessagesAsync (Msdn Documentation)
It is not clear which parameters should be passed for it to work.
Currently I call it like this:
var response = await webClient.WebApps.CreateFunctionWithHttpMessagesAsync(ResourceGroupName, FunctionAppName, functionName, new FunctionEnvelope());
In about 10-20s it returns error:
"Microsoft.Azure.Management.WebSites.Models.DefaultErrorResponseException : Operation returned an invalid status code 'InternalServerError'"
I think it is related to empty FunctionEnvelope. I tried passing various values, but none of them worked.
AFAIK there is no SDK's available. But there are REST API's which let you perform all the above operations.
List Functions
Delete Function
For updating and Deployment you can make use of the zip deployment for Azure Functions.
Generate the FunctionApp.zip using the msbuild command pointing to your csproj->
/p:DeployOnBuild=true /p:DeployTarget=Package;CreatePackageOnPublish=true
The above will generate a zip file which can be used in the later part.
Now 2nd step is to obtain the Publish credentials using this api, if you get the response it will in the below class format
public class GetPublishCredentials
{
public string Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public string Location { get; set; }
public Properties Properties { get; set; }
}
public class Properties
{
public string Name { get; set; }
public string PublishingUserName { get; set; }
public string PublishingPassword { get; set; }
public object PublishingPasswordHash { get; set; }
public object PublishingPasswordHashSalt { get; set; }
public object Metadata { get; set; }
public bool IsDeleted { get; set; }
public string ScmUri { get; set; }
}
After obtaining the credentials, follow the below piece of code to deploy or update your Azure Functions
var base64Auth = Convert.ToBase64String(Encoding.Default.GetBytes
($"{functionCredentials.Properties.PublishingUserName}:{functionCredentials.Properties.PublishingPassword}"));
var stream = new MemoryStream(File.ReadAllBytes("zip file of azure function"));
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Basic " + base64Auth);
var apiUrl = "https://" + parameters.FunctionAppName + ".scm.azurewebsites.net/api/zip/site/wwwroot";
var httpContent = new StreamContent(stream);
client.PutAsync(apiUrl, httpContent).Result;
}
Now your functionapp should be deployed.
I'm tring to set up a sample demo running ServiceStack with Silverlight. I've read this article
and I've successfully been able to invoke the method on server...
Currently my demo app is made of
Name.Web (Service and Silverlight hoster)
Name.Web.DTO contains request/response classes
Name.Silverlight (main SL application)
Name.Silverlight.DTO contains a copy (Add as Link in VS) of the class
in Name.Web.DTO
My sevice class is
public class TestService : Service
{
public object Any (TestRequest request)
{
var lst = new List<TestResponse>();
for (int i = 0; i < 20; i++)
{
var item = new TestResponse { ID = i, Descrizione = string.Format("Descr_{0}", i) };
lst.Add(item);
}
return lst;
}
}
And the response/request are really simple
[Route("/test")]
public class TestRequest : IReturn<IList<TestResponse>>
{
}
[DataContract]
public class TestResponse
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Descrizione { get; set; }
}
On silverlight part in the serviceClient_Completed I've 20 items (as service produce) but all with ID=0,Descrizione=string.Empty
What can be the reason of this? I've also tried looking with FireBug/Fiddler but I don't see anything (maybe since I'm on localhost?) or that's due to the fact serviceClient is made via ClientHttp?
var webRequest = (HttpWebRequest)WebRequestCreator.ClientHttp.Create(new Uri(_baseUri + uri));
Thanks in advance