I'm discovering AEM workflows and the flow of the Request for Approval model. I've noticed (confirmed on AEM docs) that "if the user does not have the required privileges for publishing a specific page a workflow will be triggered to notify the appropriate person of your request to publish".
Trying to find how it's triggered I've found out ReplicationProcess that handles the activation action and sends a com/day/cq/wcm/workflow/req/for/activation event. Here is where I get lost - none of the AEM OSGi console known to me covers this relationship.
How can I find the event handler that is used for handling a specific event topic?
If you know the event topic you can use bundleContext to find reference to proper EventHandler OSGi service, e.g. using AEM Groovy Console :
ServiceReference[] sr = bundleContext.getServiceReferences(org.osgi.service.event.EventHandler.class, "(event.topics=com/day/cq/wcm/workflow/req/for/activation)")
for (i=0; i< sr.length; i++) {
println bundleContext.getService(sr[i])
}
Output
com.day.cq.wcm.workflow.impl.WcmWorkflowServiceImpl#618c5804
You can also use OSGi Felix Web Console (services tab) to find it:
Related
I was wondering if anyone has seen a demo/example of using the Serilog.Extras.MSOwin package with a web api project or a example/tutorial of using Serilog with a web api project.
Any help greatly appreciated,
Jim
I will take this as question as "How do I used Serilog.Extras.MSOwin?" and given it is currently a rather small library answer here.
This reflects the current library (1.4.102) and is subject to change in the future.
Serilog.Extras.MSOwin provides two things: a Microsoft.Owin.Logging.ILoggerFactory implementation to have OWIN's logging infrastructure write to Serilog (more details about logging in OWIN in this blog post) and Guid identifier (RequestId) for each web request to aid in associating logged events.
The Logging integration is done with the following:
IAppBuilder app = ...;
Serilog.ILogger logger = ...'
app.SetLoggerFactory( new Serilog.Extras.MSOwin.LoggerFactory( logger ) );
The request id functionality needs to be registered in the OWIN pipeline:
IAppBuilder app = ...;
app.UseSerilogRequestContext("RequestId");
You will want to register that very early in the pipeline because any logging occurring before that pipeline step will not have the request id available.
You also need will need to retrieve it from the LogContext using Enrich.FromLogContext() and add that property to what you write to your sinks. For example,
const string DefaultOutputTemplate =
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} ({RequestId}) {Message}{NewLine}{Exception}";
ILogger logger =
new LoggerConfiguration().Enrich.FromLogContext()
.WriteTo
.RollingFile(
"log.txt",
outputTemplate: DefaultOutputTemplate)
.CreateLogger();
Serilog.Extras.MSOwin was superseded by SerilogWeb.Owin (which has since also been discontinued.)
I am working on a .NET MVC3 C# Application. This application is hosted on our own Server.
Now I want to Send Scheduled Email in my application like daily(at a specific time),Weekly, monthly and so on...
Currently I am using MVCMailer to send Emails in my application.
I tried Fluent Scheduler to send scheduled Emails, but it doesn't works with MVCMailer. It Works fine if I send mails without MVCMailer and for other scheduling jobs.
It gives me a ERROR NULLReferenceException and says HTTPContext cannot be null.
What can I do to solve this problem.
Also suggest me which will be the best way to send E-mails in my applicaton.
Windows Service (Having own server)
Scheduler (Fluent Scheduler)
SQL Scheduled jobs
I am attaching ERROR snapshot:
It could be that MVCMailer depends on an HttpContext, which will not exist on your scheduled threadlocal's.
You could consider scrapping MvcMailer and implementing your own templating solution. Something like RazorEngine (https://github.com/Antaris/RazorEngine), which gives you the full power of Razor without having to run ontop on an Http stack. You could still source your templates from disk so that your designers could modify it.
Then you could mail the results using the standard classes available from .net.
For e.g.:
string template = File.ReadAllText(fileLocation);//"Hello #Model.Name, welcome to RazorEngine!";
string emailBody = Razor.Parse(template, new { Name = "World" });
SmtpClient client = new SmtpClient();
client.Host = "mail.yourserver.com";
MailMessage mm = new MailMessage();
mm.Sender = new MailAddress("foo#bar.com", "Foo Bar");
mm.From = new MailAddress("foo#bar.com", "Foo Bar");
mm.To.Add = new MailAddress("foo#bar.com", "Foo Bar");
mm.Subject = "Test";
mm.Body = emailBody;
mm.IsBodyHtml = true;
client.Send(mm);
Obviously you could clean this all up. But it wouldn't take to much effort to use the above code and create some reusable classes. :)
Since you already have the FluentScheduler code set up, you may as well stick with that I guess. A windows service does also sound appealing, however I think that it's your call to make. If it's a simple mail service you are after I can't think of any reason not to do it via FluentScheduler.
I have created a full example of this available here: https://bitbucket.org/acleancoder/razorengine-email-example/src/dfee804d526ef3cd17fb448970fbbe33f4e4bb79?at=default
You can download the website to run locally here: https://bitbucket.org/acleancoder/razorengine-email-example/downloads
Just make sure to change the Default.aspx.cs file to have your correct mail server details.
Hope this helps.
Since MVC Mailer works best in the HTTP stack (i.e. from controllers), I've found that a very reliable way to accomplish this is by using Windows Task Schedule from a server somewhere. You could even spin up a micro instance on Amazon Web Server.
Use "curl" to call the URL of your controller that does the work and sends the emails.
Just setup a Scheduled Task (or Cron if you want to use *IX) to call "c:\path_to_curl\curl.exe http://yourserver.com/your_controller/your_action".
You could even spin up a *IX server on AWS to make it even cheaper.
I've created a plugin and registered it using hte registration tool. I've also added a step that is supposed to handle a message of creation of an instance. Sadly, the intended behavior doesn't occur.
My guess is that something inside the plugin crashes but I have no idea on how to debug it. Setting up breakpoints is not going to work agains on-line version, I understand, so I'm not even trying.
For legal and technical reasons, I won't be able to lift over the solution to an on-premise installation, neither. Is guessing my only option?
For server-side (plugins) I'm using ITracingService. For client-side I log everything to console. The downside with the first is that you actually need to crash the execution to get to see anything. The downside with the latter is that plugins sometimes get executed without GUI being invoked at all.
When it comes to heavier projects, I simply set up a WCF web service that I call from the plugin and write to that. That way, on one screen, I'm executing the plugin while on the other, I'm getting a nice log file (or just put the sent information to on the screen).
You could, for instance, start with a very basic update of a field on the instance of your entity that's being created. When you have that working, you can always fall back to the last working version. If you don't even get that to work, it mean, probably, that you're setting up the plugin registration incorrectly.
A very efficient way would be to lift over the solution to an on-premise version where you have full control but I see in your question that it's not en option.
In case you could lift the solution to an on-premise version, here's a link on how to debug plugins.
Don't forget that you also have access to the ITracingService.
You can get a reference to it in your Execute method and then write to it every so often in your code to log variables or courses of action that you are attempting or have succeeded with. You can also use it to surface more valuable information when an exception occurs.
It's basically like writing to a console. Then, if anything causes the plug-in to crash at runtime then you can see everything that you've traced when you click Download Log File on the error shown to the user.
Beware though - unless your plug-in actually throws an exception (deliberate or otherwise) then you have no access to whatever was traced.
Example:
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the execution context from the service provider.
IPluginExecutionContext context =
(IPluginExecutionContext)serviceProvider.GetService(
typeof(IPluginExecutionContext));
// Get a reference to the tracing service.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
try
{
tracingService.Trace("Getting entity from InputParameters...");
// may fail for some messages, since "Target" is not present
var myEntity = (Entity)context.InputParameters["Target"];
tracingService.Trace("Got entity OK");
// some other logic here...
}
catch (FaultException<OrganizationServiceFault> ex)
{
_trace.Trace(ex.ToString());
while (ex.InnerException != null)
{
ex = (FaultException<OrganizationServiceFault>)ex.InnerException;
_trace.Trace(ex.ToString());
}
throw new InvalidPluginExecutionException(
string.Format("An error occurred in your plugin: {0}", ex));
}
catch (Exception ex)
{
_trace.Trace(ex.ToString());
while (ex.InnerException != null)
{
ex = ex.InnerException;
_trace.Trace(ex.ToString());
}
throw;
}
}
Does someone know how we can have Starteam send email notifications when a check in occurs? We are using Starteam 2006 R2.
Unfortunately StarTeam doesn't offer the ability to execute post-checkin actions. You may be able to use an application like Cruise Control to monitor your repository for changes and then take action upon seeing them.
I had a similar need a few months ago, this is what I discovered:
Starteam does not have commit hooks but it does have Starteam MPX (borland.com). From that link,
StarTeamMPX is a framework for publish/subscribe messaging. The StarTeamMPX Server uses an advanced caching and communication technology that both improves the performance of StarTeam clients and extends the scalability of the StarTeam Server.
Ok, so, we can subscribe to events. It's looking promising.
There is a Java API (borland.com) for Starteam, create an app using this API with your own emailing implemention of the CheckinListener interface. The app will then have to connect to Starteam, find any views that you're interested in and register listeners against them. And then wait.
Your listener will receive CheckinEvents and can interrogate these. Unfortunately, it appears to be on a file by file basis. I couldn't see anything in the API to say "commit finished", only "file finished". You are able to discover if a commit was cancelled. I don't know how easy it is to combine file checkin events back into a complete check in event.
*StarteamMPX is an extension (paid) to Starteam, it is available for 2006 R2. All of this is clearly only applicable if it is enabled.
My Experience:
My company didn't have that extension enabled, and to enable it required upgrading i.e. more money. So it didn't happen (I think it's painful enough paying for Starteam to begin with). At this point I abandoned my research and none of the above was ever implemented this. I hope this is some use to someone.
I've been doing some homework into this topic too, so will share what I've learnt.
MicroFocus now offer a Notification Agent tool for this sort of thing:
http://www.youtube.com/watch?v=QTKAT-ufkIs
It's an extra you pay for though.
I've been also pondering how to "roll-your-own" via advice given in Dan's post above. Yes, MPX does seem to be the way to go, although after studying the CheckinListener, this isn't the class you're after. To clarify, CheckinListener is used by the client performing the check-in, so that it can monitor progress of the check-in (perhaps to display a progress bar, that sort of thing).
Here's some sample-code of what listening to MPX events looks like:
Server s = new Server(strAddress, nPort);
s.connect();
s.enableMPX(); // must do this for MPX support
s.logOn(strUsername, strPassword);
Project p = s.findProject("mylovelyproject");
View v = p.s.findView("mylovelyview");
ItemListener listener = new ItemListener()
{
public void itemAdded(ItemEvent e)
{
System.out.println("itemAdd() - " + e.getNewItem().getComment());
}
public void itemMoved(ItemEvent e)
{
System.out.println("itemMoved() - from: " + e.getOldItem().getParentFolderHierarchy() + ", to: " + e.getNewItem().getParentFolderHierarchy());
}
public void itemChanged(ItemEvent e)
{
System.out.println("itemChanged() - " + e.getNewItem().getComment());
System.out.println(" - from: v" + e.getOldItem().getDotNotation().toString());
System.out.println(" - to: v" + e.getNewItem().getDotNotation().toString());
User locker = e.getNewItem().getLocker();
if (locker != null)
System.out.println(" - locked by:" + locker.getDisplayName());
else
System.out.println(" - not locked");
}
public void itemRemoved(ItemEvent e)
{
System.out.println("itemRemoved() - " + e.toString());
}
};
v.addItemListener(listener, s.getTypes().FILE);
The MPX-related items to focus on here are new ItemListener() (what to do about the events you listen to) and v.addItemListener() (which starteam view you want to listen to).
The sample code will spit out various print output to the console as files in your view are added/modified/moved/deleted.
Apart from ItemListener, you also have ViewListener and ProjectListener. Each interface provides a different scope of events to listen for, more info on this in the sdk docs, also a nice article here:
http://conferences.embarcadero.com/article/32231#MPXEventHandling
So if you want to roll-your-own notification emails, these MPX events provide part of your answer (a way to listen to these change-events).
Other aspects you'll need to look into after this are:
How to allow users to subscribe to various servers/projects/views, to decide what they want to listen to.
How to email to the user what they want (StarTeam's Server class offers a .SendMail() method, which can help here).
Once all these bases are covered, you should have something that does the trick. I'll be working on something like this myself over the coming days, I'll share what I can.
Im using a org.osgi.util.tracker.ServiceTracker (PrintableServiceTracker implements ServiceTrackerCustomizer and simply prints when a new service is added).
Filter filter = bc.createFilter("(objectClass=se.enea.print.Printable)");
tracker = new ServiceTracker(bc, filter, new PrintableServiceTracker(bc));
I've read about "pseudo registration" in the new ebook "OSGi in action" and I wonder if I have to do pseudo registration explicitly or if the framwork handles this automatically?
(Will already installed Printable services be caught by the ServiceTracker. will ServiceTracker.addingService(ServiceReference) be called for each of the pre installed Printable services)
Not sure what pseudo registration means, but the method addingService in PrintableServiceTracker will be called not only for new services but also for existing services.