How does one go about creating action filters in Azure Mobile Service? And, yes I do wish use Autofac constructor injection of dependencies.
Glad for any help and pointers!
Thanks
Are you looking to register global ActionFilters? It should work very similarly to Web API. So you can do something like:
HttpConfiguration config = ServiceConfig.Initialize(new ConfigBuilder(options));
config.Filters.Add(new MyFilter());
See this post for details on registering new services with Autofac: http://blogs.msdn.com/b/azuremobile/archive/2014/03/28/making-it-yours-configuring-mobile-services-net-backend.aspx. You'd use the ConfigBuilder constructor overload that takes a parameter named dependencyInjectionConfig.
Related
I have just started my first loopback project and chosen loopback4 version for the application. Its purely a server application which will interact with databases (Redis and mongodb) and will call external API services due to micro-service architecture.
Now, I have 3 datasources in my application i.e. mongodb, Redis, and REST based datasource to call external services. I am facing 2 problems in going forward.
1. Environment specific configurations of Datasources: I need to maintain configuration for all three datasources according to the NODE_ENV environment variable. For lb3 i found this solution,
https://loopback.io/doc/en/lb3/Environment-specific-configuration.html#data-source-configuration
which does not work in lb4. One solution is to add configuration files having names mongodb.staging.json and mongodb.production.json and same for redis and rest datasources in directory src/datasources, and load this config according to NODE_ENV variable using if condition and pass it to the constructor of datasource. It works but it does not seem nice, as it should be application's responsibility to do this.
Can somebody suggest me lb3 equivalent solution for the above?
2. Calling External APIs via datasource: in lb4, To call external services its recommended to have a separate REST based datasource and its service to call it via controller. Now, In REST datasource config, one has to define a template of all the API calls which will happen to the external service https://loopback.io/doc/en/lb4/REST-connector.html#defining-a-custom-method-using-a-template.
As my application calls external service heavily with relatively large number of request parameters. It becomes really messy to declare each API call with its request params and to maintain this in the datasource config which will be environment specific.
Can somebody tell me a more robust and cleaner alternative of the above problem?
Thanks in advance!!
Using environment variables in datasource configs
The datasource config is simply a JSON file that's imported in into *.datasource.ts. Hence, you can replace that JSON file with a Typescript file and import it accordingly. LoopBack 4 does not provide any custom variable substitution mechanism. Instead, it is recommended to use process.env.
Recent CLI versions replace the JSON config in favour of using a single Typescript file:
import {inject} from '#loopback/core';
import {juggler} from '#loopback/repository';
const config = {
name: 'db',
connector: 'memory',
};
export class DbDataSource extends juggler.DataSource {
static dataSourceName = 'db';
static readonly defaultConfig = config;
constructor(
#inject('datasources.config.db', {optional: true})
dsConfig: object = config,
) {
super(dsConfig);
}
}
The dependency injection in the constructor allows you to override the config programmatically via the IoC container of the application.
Further reading
https://loopback.io/doc/en/lb4/DataSources.html
Calling external APIs without REST connector
The REST connector enforces a well-defined interface for querying external APIs so as to be able to do validation before sending out the request.
If this is not favourable, it is possible to create a new Service as a wrapper to the HTTP queries. From there, you can expose your own functions to handle requests to an external API. As Services do not need to follow a rigid structure, it is possible to customize it to your use-case.
It is also possible to create a new request directly inside the controller using either built-in or external libraries.
Overall, there isn't a 100% right or wrong way of doing certain things in LoopBack 4. Hence why the framework provides numerous ways to tackle the same issue.
I have an application built from a series of web servers and microservices, perhaps 12 in all. I would like to monitor and, importantly, map this suite of services in Applications Insights. Some of the services are built with Dot Net framework 4.6 and deployed as Windows services using OWIN to receive and respond to requests.
In order to get the instrumentation working with OWIN I'm using the ApplicationInsights.OwinExtensions package. I'm using a single instrumentation key across all my services.
When I look at my Applications Insights Application Map, it appears that all the services that I've instrumented are grouped into a single "application", with a few "links" to outside dependencies. I do not seem to be able to produce the "Composite Application Map" the existence of which is suggested here: https://learn.microsoft.com/en-us/azure/application-insights/app-insights-app-map.
I'm assuming that this is because I have not set a different "RoleName" for each of my services. Unfortunately, I cannot find any documentation that describes how to do so. My map looks as follow, but the big circle in the middle is actually several different microservices:
I do see that the OwinExtensions package offers the ability to customize some aspects of the telemetry reported but, without a deep knowledge of the internal structure of App Insights telemetry, I can't figure out whether it allows the RoleName to be set and, if so, how to accomplish this. Here's what I've tried so far:
appBuilder.UseApplicationInsights(
new RequestTrackingConfiguration
{
GetAdditionalContextProperties =
ctx =>
Task.FromResult(
new [] { new KeyValuePair<string, string>("cloud_RoleName", ServiceConfiguration.SERVICE_NAME) }.AsEnumerable()
)
}
);
Can anyone tell me how, in this context, I can instruct App Insights to collect telemetry which will cause a Composite Application Map to be built?
The following is the overall doc about TelemetryInitializer which is exactly what you want to set additional properties to the collected telemetry - in this case set Cloud Rolename to enable application map.
https://learn.microsoft.com/en-us/azure/application-insights/app-insights-api-filtering-sampling#add-properties-itelemetryinitializer
Your telemetry initializer code would be something along the following lines...
public void Initialize(ITelemetry telemetry)
{
if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
{
// set role name correctly here.
telemetry.Context.Cloud.RoleName = "RoleName";
}
}
Please try this and see if this helps.
I am trying to implement DI using Autofac IOC in Azure function.
I need to build the container, but not sure where to put the code to build the container
I did write a blog entry for doing dependency injection with Autofac in Azure Functions. Have a look here:
Azure Function Dependency Injection with AutoFac: Autofac on Functions
It follows a similar approach like the one by Boris Wilhelms.
Another implementation based on Boris' approach can be found on github: autofac dependency injection
-- update ---
With Azure Function v2 it is possible to create nuget packages based on .net standard. Have a look onto
Azure Functions Dependency Injection with Autofac: Autofac on Functions nuget Package
I think for now you would need to do something ugly like:
public static string MyAwesomeFunction(string message)
{
if (MyService == null)
{
var instantiator = Initialize();
MyService = instantiator.Resolve<IService>();
}
return MyService.Hello(message);
}
private static IService MyService = null;
private static IContainer Initialize()
{
// Do your IoC magic here
}
While Azure Functions does not support DI out of the box, it is possible to add this via the new Extension API. You can register the container using an IExtensionConfigProvider implementation. You can find a full example DI solution in Azure here https://blog.wille-zone.de/post/azure-functions-proper-dependency-injection/.
Azure Functions doesn't support dependency injection yet. Follow this issue for the feature request
https://github.com/Azure/Azure-Functions/issues/299
I've written a different answer to the main question, with a different solution, totally tied to the main question.
Previous solutions were either manually initializing a DI or using the decorator way of doing it. My idea was to tie the DI to the Functions Builder in the same way we do with aspnet, without decorators.
I don't know why my post got deleted by #MartinPieters, it seems that it was not even read.
I found no way to officially disagree with that decision, so I kindly ask that the moderator read my answer again and undelete it.
You can do it using a custom [inject] attribute. See example here https://blog.wille-zone.de/post/azure-functions-proper-dependency-injection/
I'm trying to follow this link to set up logging for my ASP.NET 5 app in azure https://docs.asp.net/en/latest/fundamentals/logging.html but can't make it work.
What is the way to do it?
You can configure logging through the Startup constructor. Here is a sample:
public Startup(ILoggerFactory loggerFactory)
{
var serilogLogger = new LoggerConfiguration()
.WriteTo
.TextWriter(Console.Out)
#if DNX451
.WriteTo.Elasticsearch()
#endif
.MinimumLevel.Verbose()
.CreateLogger();
loggerFactory.MinimumLevel = LogLevel.Debug;
loggerFactory.AddSerilog(serilogLogger);
}
That's all you need for configuration. From there, you can inject either ILoggerFactory or ILogger<T> (which is mostly the type for the class you want to inject the logger into) to the places you want to log stuff.
My sample configuration makes use of Serilog.Framework.Logging version 1.0.0-rc1-final-10071. Also, under dnx451, it will use Serilog.Sinks.ElasticSearch version 2.0.60.
In Azure Web App, there is no difference the way you configure it. You just need to choose the right provider.
You can see the entire sample here. Also check out ASP.NET 5 and Log Correlation by Request Id which might give you some more ideas.
At this point Azure AppService doesn't support ASP.NET 5 standard trace logging. Here is a potential workaround:
https://github.com/davidebbo-test/ConsoleInterceptor
Is there a way to expose a Java rest web service in Liferay but not in a portlet, that can receive JSON request and store the data in Journal Article?
Therefore when a user logs into Liferay they will be see web content
Yes there is : JSONWebServiceActionsManagerUtil.registerJSONWebServiceAction
For instance :
Class<?> serviceImplClass;
Method serviceMethod;
Object serviceImpl;
String path = jsonWebServiceMappingResolver.resolvePath(serviceImplClass, serviceMethod);
String method = jsonWebServiceMappingResolver.resolveHttpMethod(serviceMethod);
JSONWebServiceActionsManagerUtil.registerJSONWebServiceAction("/yourwspath", serviceImpl, serviceImplClass, serviceMethod, path, method);
You should then be able to see the new web service in http://SERVER/api/jsonws
Well yes, Liferay has a full API (even JSON-based, SOAP optional, no classic REST though) that you can use. A simple Stackoverflow answer is not the right place to give a full introduction on how to work with Liferay's API, but you might want to look up Servicebuilder (which is used to create Liferay's API) and then look at JournalArticleService and related services: The Web Content Management API is called "Journal" in Liferay (for historical reasons)