Service or event? - oop

What is the best way to go about calling various services that are internally only (i.e. no client code can invoke the logic)?
IProcessService - will run various things and make changes to a domain entity, however when certain data changes on this domain entity we want to send out a notification (add a new record to notification table, record the current user and type of notification, and maybe even send out email).
E.g. Add a client, as soon as we add a client - we want to save a record in the db that a client has been added, if we have a supplier confirmed, we have a delivery date confirmed we want to fire off notifications.
My notifications are a way of logging all activity related to the process of a Order...
Is using a pub sub approach common/ event listers etc?
NOTE: I am using Linq To Sql, and a service layer to communicate with my asp.net mvc app, all my business logic/validation/rules etc reside inside my service layer...

Check out Domain Events.
When you call client.ConfirmDeliveryDate(), it would raise a domain event (DeliveryDateConfirmed). You'd then have a class listening to this event: EmailCustomerWhenDeliveryDateConfirmed.

Related

Where to put calls to 3rd party APIs in Apigility/ZF2?

I have just completed my first API in Apigility. Right now it is basically a gateway to a database, storing and retrieving multi-page documents uploaded through an app.
Now I want to run some processing on the documents, e.g. process them through a 3rd party API or modify the image quality etc., and return them to the app users.
Where (in which class) do I generally put such logic? My first reflex would be to implement such logic in the Resource-Classes. However I feel that they will become quite messy, obstructing a clear view on the API's interface in the code and creating a dependency on a foreign API. Also, I feel limited because each method corresponds to an API call.
What if there is a certain processing/computing time? Meaning I cannot direct respond the result through a GET request. I thought about running an asynchronous process and send a push notification to the app, once the processing is complete. But again, where in the could would I ideally implement such processing logic?
I would be very happy to receive some architectural advice from someone who is more seasoned in developing APIs. Thank you.
You are able to use the zf-rest resource events to connect listeners with your additional custom logic without polluting your resources.
These events are fired in the RestController class (for example a post.create event here on line 382).
When you use Apigility-Doctrine module you can also use the events triggered in the DoctrineResource class (for example the DoctrineResourceEvent::EVENT_CREATE_POST event here on line 361) to connect your listeners.
You can use a queueing service like ZendQueue or something (a third party module) built on top of ZendQueue for managing that. You can find different ZF2 queueing systems/modules using Google.
By injecting the queueing service into your listener you can simply push your jobs directly into your queue.

Is there a way to listen to the upload events in the EMC's Documentum via .NET API?

i need to implement a windows service that connects to EMC's Documentum and receives an event every time a document is loaded.
The event should contain the reference to the document itself.
Is there a way to do it via API or do i have to do polling using a web service?
Quickest would be to implement this via polling.
Your Windows service can either
access DFS exposed service (that you need implement on DCTM side)
access docbase directly using DFC/.NET
But the question here is what is that you want to check?
Document loaded - If you are referring to dm_document object created (e.g. by a user/system or some sort of upload functionality) - you will need to register dm_audittrail for that event. Once that is in place your service or API call can check for dm_audittrail entries.
Alternatively you could use Documentum BOF (Business Object Framework) to write custom code that would be triggered every time for instance new document is being crated (or updated) - i.e. on specific predefined event.
This custom code could do whatever you like, like for instance broadcast JMS message to a queue that your Windows Service is listening. You see to implement the thing that you want (event based notification) you need some communication channel between your application and a content server.
Or simply just poll Docbase it every x seconds.
Guess you already know this but a lot of info can be found on:
https://community.emc.com/community/edn
Also BOF Guide (older version): https://developer-content.emc.com/developer/downloads/BusinessObjectsDevelopersGuide.pdf
I think you can use Rest Service. Documentum whole functionality exposed in rest service. https://community.emc.com/community/labs/archivedprojects/dctm_rest

Is it OK to flush the EntityManager from within a domain Service?

I have a domain service called OrderService, with a saveOrder() method:
class OrderService
{
// ...
public function saveOrder(Order $order)
{
$this->orderRepository->add($order);
// $this->entityManager->flush();
$this->notificationService->notifyOrderPlaced($order);
}
}
saveOrder() adds the order to the repository (which internally calls persist() on the EntityManager), then passes the Order to the NotificationService to send appropriate notifications (email, SMS).
The problem is, while NotificationService needs the order ID to include in the notifications, the Order has no ID yet as it's not been persisted to the DB (the ID is auto generated).
The obvious solution seems to pass the EntityManager as a dependency to the OrderService, and flush() right after the repository add() method, as in the example above. But I've always been reluctant to make the domain Services aware of the EntityManager, preferring to let them talk only to repositories, or other services.
What are the drawbacks, if any, of a domain Service having a dependency on the EntityManager?
Is there a better alternative?
Note: I'm using PHP and the Doctrine ORM, but I believe the same principles apply to Java & Hibernate as well.
You may want to consider one of these options (or both)
Make this service an Application layer service instead of a Domain service. It's perfectly OK to call your change tracker in an Application service since it is supposed to know about the application context and progress in the current use case. Typical application services will commit the business transaction/ask the change tracker to save changes when they're done, so why not call it to generate Id's as well ?
If you're concerned about the database being involved in the middle of a use case, maybe you can find an equivalent to NHibernate's Guid.Comb strategy to make your ORM generate an Id without issuing an INSERT to the database right away.
Use a Domain event. Upon creation, an Order could inform the world that it has been newed up. The notification service would handle the event and send appropriate notifications. You'll find an example of that here (it also includes an Application layer service to take care of the business transaction).

WCF Data Service Change Tracking: How to cancel save changes and revert to original values for an object

I have a WCF Data Service that is wrapping an Entity Framework 4 data model. I am connecting a WPF client to the service using the WCF Data Services Client library.
Is it possible in WCF Data Services to undo / cancel changes to tracked objects ?
scenario : In the UI I allow a user to edit an object. I have save and cancel buttons. If the user chooses to save I call SaveChanges() on my WCF context and changes are sent to the database via the WCF service. If the user clicks cancel I want to undo the changes and revert to the original property values of the current object.
I know that the WCF data services client library has change tracking built in - but I cannot find any way at accessing this information.
In Entity Framework the context supports the Refresh method and you can specify RefreshMode.StoreWins and pass in the object - this will effectively cancel / undo any changes.
documented here : http://msdn.microsoft.com/en-us/library/bb896255.aspx
Any suggestions on how I can achieve the same thing in WCF DataServices in my client application ?
cheers
Chris
The only "solution" I know of is:
var oldMergeOption = _service.MergeOption;
_service.MergeOption = MergeOption.OverwriteChanges;
try {
_service.YourQueryable.Where(x => x.Id==oldObject.Id).Single();
} finally {
_service.MergeOption = oldMergeOption;
}
This should replace the values of "oldObject" with the values stored in the DB. However, I'm not sure if the object returned by Single() will always be the same as "oldObject".
I typically refrain from operating on entities within the DataServiceContext until I'm ready to commit those changes to the database. I don't treat my entities as part of my domain model so I create a specific domain model that adapts my model objects to entity objects using adapters and a repository class. This way, all operations within by domain model are self-contained until I'm ready to commit them to the database. A fantastic article from Ben Day on what I'm referring to can be found here: http://visualstudiomagazine.com/articles/2011/04/01/pfcov_silverlight-mvvm-tips.aspx

Entity Framework 4.1: how to work with per call life time data context?

According to this post, I am using a data context per call, so in each method of my WCF service, I use a using block to create a new data context.
But I have some doubts in the form to work in this way.
For example, I use a method getAllCLients() from my repository to get all the clients of the data base, then the service send to the client that call the method a list with all the clients. Then the user modify the information of some of them, three for example. The modify client perhaps I can add to a list that have the modified clients.
When I want to update this three clients, I can call a method updateClients() which receive a list of modified clients. How I am use a new data context per each method, in updateCients() get a new dataContext, without entities, so I think that I have to follow this steps:
1.- create a new data context which has the clients that I want to update. SO I need to specified the conditions for that. This is an extra operation (I get the clients before with the getAllClients() method), so I need to get again the clients.
2.- go throw the clients collection of the DBSet (I use EF 4.1) and change the information. This makes me to go throw the list that I receive from the client application too. So I must to go throw two lists. This needs resources.
3.- save the changes. This is needed anyway, so it has no required more work.
There is any way to make the step 2 easily? exist some method in dataContext to pass the values from my modified client to the client in the data context? I use POCO entities, perhaps it exists an easy way to do that.
Other question is about concurrency. If I control the concurrency with pesimistic concurrency that allow EF (with a timestamp field for example), is it better to call the updateClient() one for each client or better to pass a list with all the clients? I mean that if I use a list as parameter, if there is a concurrency issue with one client,the second for example, the first client will be update correctly, but the second not and the third neither. How can I notify to the user that there is problems with some clients?
To resume, I would like to know the best way to make updates when I have a short life datacontext.
Thanks.
Daimroc.
The service is disconnected scenario so when your client passes backs modified records you just need to process them as modified. You don't need to load all records from database for that.
public void SaveClients(List<Client> modifiedClients)
{
using (var context = new Context())
{
modifiedClients.ForEach(c =>
{
context.Entry(c).State = EntityState.Modified;
});
context.SaveChanges();
}
}
If you are using per call service and every service operation needs context you can move your context instancing to service constructor because service instance will live only to server single service call = you don't need using for every call. If you do that don't forget to implement IDisposable on your service to dispose context.
Other question is about concurrency. If I control the concurrency with
pesimistic concurrency that allow EF (with a timestamp field for
example), is it better to call the updateClient() one for each client
or better to pass a list with all the clients?
EF doesn't support pesimistic concurrency out of the box. Using timestamp is optimistic concurrency because it allows others to use the record. Pesimistic concurrency is application logic where other client is not able to select locked record for update.
The concurrency is resolved per record but the problem in this case is transaction. Each call to SaveChanges results in transaction used to process all changes in the database. So if any of your modified records is not up to date you will get concurrency exception and whole transaction is rolled back = no record is updated.
You can still overcome the issue by passing list of modified records to the service (reducing roundtrips between client and service is a best practice) but you can process each record separately by calling SaveChanges for every single record. Anyway this should be very carefully considered because each call to SaveChanges is like separate unit of work - is it really what you want?
Btw. the best practice is to make your service statless. You should avoid maintaining data between service calls and this example really doesn't need it.