How to cancel delete using AbstractMongoEventListener? - spring-mongodb

Can I cancel delete event using onBeforeDelete method of MongoGenreCancelDeleteEventsListener? If yes then how?
#Component
public class MongoGenreCancelDeleteEventsListener extends AbstractMongoEventListener<Genre> {
private final BookRepository bookRepository;
#Override
public void onBeforeDelete(BeforeDeleteEvent<Genre> event) {
super.onBeforeDelete(event);
// check conditions and cancel delete
}
}

I know this is an old question, but I had the same issue and I found a solution.
Basically, your code should become like this:
#Component
public class MongoGenreCancelDeleteEventsListener extends AbstractMongoEventListener<Genre> {
private BookRepository bookRepository;
#Override
public void onBeforeDelete(BeforeDeleteEvent<Genre> event) {
super.onBeforeDelete(event);
boolean abort = false;
//do your check and set abort to true if necessary
if (abort) {
throw new IllegalStateException(); //or any exception you like
}
}
}
The thrown exception prevents the operation from going further and it stops there. Also, the exception gets propagated to the caller (anyway, it is wrapped inside a UndeclaredThrowableException, so this is what you should catch; make sure that the wrapped exception is indeed the one you've thrown by calling the getCause() method).
Hope it helps.

Related

MDB exception handling

I have an MDB that calls some methods in its onMessage() method.Inside the catch block of onMessage() I run an update query using preparestatement.I notice that if the flow reaches the catch block it does not commit the update statement.Is it not possible to do that inside the catch block of an MDB?My onMessage() methos is like this
public void onMessage(Message message) {
try{
someMethod()
}
catch(Throwable o)
{
someUpdateMethod()//update query runs here
}
}
Whatever threw the exception caused the transaction context into rollback only mode.
When onMessage returns all transactional resources will be called to rollback. This includes the datasource used for the prepared statement in someUpdateMethod().
To get the update committed it must be executed in a separate transaction. Do this by calling another stateless session bean with the #TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) on the method.
#MessageDriven(...
public class MyMdb inpelements MessageListener
#EJB
Updater updater;
#Override
public void onMessage(Message message) {
try {
someMethod();
}
catch(Throwable o) {
updater.someUpdateMethod();
}
}
}
The stateless session EJB that executes the update in a separate transaction.
#Stateless
public class Updater {
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public String someUpdateMethod() {
//update query runs here
}
}

Getting ElementNotFound Exception in TestNG

The following code is for login and then click on Create quest Link. It does not click on the link and gives ElementNotFound exception and skips the test. It just logs in and logout. Please Help
public class Edit_Question {
WebDriver driver = new FirefoxDriver();#
BeforeTest
public void load() {
driver.get("Page url");
}
# Test
public void login() throws InterruptedException {
driver.findElement(By.id("userid")).sendKeys("4060#jhg.com");
driver.findElement(By.id("password")).sendKeys("mpcyn2");
driver.findElement(By.id("emLoginLink")).click();
Thread.sleep(10000);
}# Test
public void ques() throws InterruptedException {
//select create questions
driver.findElement(By.xpath("//xpath link")).click(); //throws ElementNotFound exception
Thread.sleep(5000);
}# Test
public void logout() {
//logout
driver.findElement(By.partialLinkText("SeeharackTest1, SherrodUATT")).click();
driver.findElement(By.id("logoutLink")).click();
}
# AfterSuite
public void close() {
driver.close();
}
}
The order of execution is not gauranteed. You need to use dependOnMethods to gaurantee order here. So ques should depend on login and logout should depend on ques to gaurantee the order of execution.
Other observations :
1. Try using #BeforeClass instead of #BeforeTest and #AfterClass instead of #AfterSuite
2. Avoid using sleeps wherever possible. Wait for a particular element instead.
3. Shouldn't this entire flow be one testcase?
Hope it helps.

Akka/Camel UntypedConsumerActor not consuming from file-based queue

I'm trying to put together my first Akka/Camel application from "scratch" (read, "noob") using the following lib versions:
akka-camel: 2.2.0-RC1
According to all of the documentation I can find (Akka docs, user groups, etc.) all I have to do to consume from a file-based queue is set up my system this way:
Main class:
actorSystem = ActorSystem.create("my-system");
Props props = new Props(Supervisor.class);
ActorRef supervisor = actorSystem.actorOf(props, "supervisor");
Camel camel = CamelExtension.get(actorSystem);
CamelContext camelContext = camel.context();
camelContext.start();
Supervisor class:
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.camel.javaapi.UntypedConsumerActor;
import org.apache.camel.Message;
/**
* Manages creation and supervision of UploadBatchWorkers.
*/
public class Supervisor extends UntypedConsumerActor {
#Override
public String getEndpointUri() {
return "file:///Users/myhome/queue";
}
#Override
public void preStart() {
String test = "test";
}
#Override
public void onReceive(Object message) {
if (message instanceof CamelMessage) {
// do something
}
}
My problem is that even though I know the supervisor object is being created and breaks during debugging on the preStart() method's "test" line (not to mention that if I explicitly "tell" it something it processes fine), it does not consume from the defined endpoint, even though I have another application producing messages to the same endpoint.
Any idea what I'm doing wrong?
Ok, the problem was my own fault and is clearly visible in the example code if you look at the Consumer trait from which the UntypedConsumerActor inherits.
This method:
#Override
public void preStart() {
String test = "test";
}
overrides its parent's preStart() method, right? Well, that parent method is actually the one that registers the consumer with the on-the-fly created endpoint, so while you can override it, you must call super() or it will not work.
Hope this is useful to someone down the road!
Try changing your instanceof inside of onReceive to this:
if (message instanceof CamelMessage){
//do processing here
}
Where CamelMessage is from package akka.camel. That's what the examples in the akka camel docs are doing.

Handing exception in BLL and return to client (either winforms or webforms)?

I am looking for the best way to do exception handling, for example.. when an error occurs in the business logic layer, is the best way to stop the METHOD using a catch and return an EVENT to the presentation layer?
What should this event contain?
Or should i always BUBBLE up exceptions and handle them in the presentation layer?
Anyone have some good links and required reading on this with regards to the best way of handling exceptions and how to handle them in the client ...
For example if i get a NullException in the BLL than i can catch this.. but whats the best way and return to the presentaiton layer and informing it of the issue..
Event? or another try / Catch in the presentation?
You can do several things;
Focus on improving the user experience when an unexpected error presents itself.
Always log errors either in eventlog or database.
Implement sufficient infrastructure to not let exceptions happen unless they are system exceptions.
Use throw instread of throw exception
Some links to help you:
http://today.java.net/pub/a/today/2003/12/04/exceptions.html
http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html
http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
There are several ways to do it:
1) Throwing exceptions with describing message inside.
2) Firing events
3) Using special interfaces to interact with the user.For example you can implement something like IUiCallbacks interface and send the object, implementing this interface, to the BLL class or method. Later, method in BLL can call IUiCallbacks.SendMessage() or IUiCallbacks.SendError() to notify presentation. And you can have different classes, such as WinFormsUiCallbacks, WebFormsUiCallbacks and SilentUiCallbacks, implementing this interface.
I usually use 1) and 3)
Example of 3) as requested:
public interface IUiCallbacks
{
void SendMessage(string message);
void SendException(string message, Exception ex);
}
public class WinFormsUiCallbacks : IUiCallbacks
{
public void SendMessage(string message)
{
MessageBox.Show(message);
}
public void SendException(string message, Exception ex)
{
MessageBox.Show(string.Format("Unfortunately, the following errror has occurred:{0}{1}", Environment.NewLine, ex.Message));
}
}
public class OrderService
{
private IUiCallbacks _iUiCallbacks;
...
public OrderService() { ... }
public OrderService(IUiCallbacks iUiCallbacks)
{
_iUiCallbacks = iUiCallbacks;
}
...
public void AddOrder(Order order)
{
...
if(OrderAlreadyExists(order))
{
if(_iUiCallbacks != null)
_iUiCallbacks.SendMessage("The order can not be added, because it is already accepted.");
return;
}
...
}
...
}
So it can be used like this:
public partial class OrderForm : Form
{
...
public void btnAddOrderFromExcel_Click(...)
{
Order order = LoadOrderFromExcel(...);
OrderService orderService = new OrderService(new WinFormsUiCallbacks());
orderService.AddOrder(order);
}
...
}

How can I get the current exception in a WinForms TraceListener

I am modifying an existing WinForms app which is setup with a custom TraceListener which logs any unhandled errors that occur in the app. It seems to me like the TraceListener gets the message part of the exception (which is what gets logged), but not the other exception information. I would like to be able to get at the exception object (to get the stacktrace and other info).
In ASP.NET, which I am more familiar with, I would call Server.GetLastError to get the most recent exception, but of course that won't work in WinForms.
How can I get the most recent exception?
I assume that you have set an event handler that catches unhandled domain exceptions and thread exceptions. In that delegate you probably call the trace listener to log the exception. Simply issue an extra call to set the exception context.
[STAThread]
private static void Main()
{
// Add the event handler for handling UI thread exceptions
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
// Add the event handler for handling non-UI thread exceptions
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
...
Application.Run(new Form1());
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MyTraceListener.Instance.ExceptionContext = e;
Trace.WriteLine(e.ToString());
}
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
// similar to above CurrentDomain_UnhandledException
}
...
Trace.Listeners.Add(MyTraceListener.Instance);
...
class MyTraceListener : System.Diagnostics.TraceListener
{
...
public Object ExceptionContext { get; set; }
public static MyTraceListener Instance { get { ... } }
}
On the Write methods in MyTraceListener you can get the exception context and work with that. Remember to sync exception context.

Resources