Synchronising with an external system

Discussions relating to plugin development, and the Jiwa API.

Synchronising with an external system

Postby SBarnes » Fri Mar 06, 2020 4:44 pm

At the moment I am working on having Jiwa stay synchronised with an external system for debtors, inventory and staff.

To achieve this on the save end of these objects I am logging that the object was changed to a table, and then using a windows service to update the external system system, the reason for doing it this way is the external system may not always be available so the log table has a processed flag in it to allow retrying.

The issue arises when a delete of any of these entities is done and my workaround at the moment would be to serialise the object and put the XML in the log table and then simply desrialise it into an object to work with, the only concern I have is where you could have a deleted order and a deleted debtor together but am I right in assuming you can not delete a debtor or product once a referring object such as sales order order etc are created against them?
Regards
Stuart Barnes
stuart@attkey.com.au
SBarnes
Jiwa Sensei
Jiwa Sensei
 
Posts: 856
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 74

Re: Synchronising with an external system

Postby Mike.Sheen » Fri Mar 06, 2020 5:50 pm

SBarnes wrote:am I right in assuming you can not delete a debtor or product once a referring object such as sales order order etc are created against them?


Correct - you cannot delete a debtor or product if they are used on things like sales orders.

You could create a product, add it to a new sales order - and then subsequently delete the sales order line, and also then delete the product - and in your case your queue table will then have a sales order DTO containing a product which no longer exists.

But that's probably an edge case not worth worrying about.
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Jiwa Shihan
Jiwa Shihan
 
Posts: 1678
Joined: Tue Feb 12, 2008 11:12 am
Location: North Sydney
Topics Solved: 523

Re: Synchronising with an external system

Postby SBarnes » Fri Mar 06, 2020 6:03 pm

Thanks,

But it is only products, debtors and staff but orders may be an issue on another possible project that involves an external shopping cart where I am thinking of the same approach.

One of the other issues that will be a challenge given the update in these cases needs go both ways otherwise the whole interface is useless is not drop into an infinite loop of update round robin but I think I have that sorted with the idea of checking whether or not the external update needs to be applied to Jiwa i.e are the entities already equal.
Regards
Stuart Barnes
stuart@attkey.com.au
SBarnes
Jiwa Sensei
Jiwa Sensei
 
Posts: 856
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 74

Re: Synchronising with an external system

Postby Mike.Sheen » Fri Mar 06, 2020 9:34 pm

SBarnes wrote:One of the other issues that will be a challenge given the update in these cases needs go both ways otherwise the whole interface is useless is not drop into an infinite loop of update round robin but I think I have that sorted with the idea of checking whether or not the external update needs to be applied to Jiwa i.e are the entities already equal.


A diff of the XML would work, as you suggested - to indicate if anything has changed and if not not bother importing anything which would trigger another export. It's a fairly expensive operation, but better than an infinite sync.

Depending on how much control you have at the external end of the sync - you might be able to control this by setting a field when deserialising from Jiwa, and either in the external system not signal back a change to Jiwa is that field is present or a certain value, or you could have the import into Jiwa ignore signals from the external system if such a field is present or has a certain value.
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Jiwa Shihan
Jiwa Shihan
 
Posts: 1678
Joined: Tue Feb 12, 2008 11:12 am
Location: North Sydney
Topics Solved: 523

Re: Synchronising with an external system

Postby SBarnes » Sat Mar 07, 2020 11:22 am

Mike.Sheen wrote:Depending on how much control you have at the external end of the sync - you might be able to control this by setting a field when deserialising from Jiwa, and either in the external system not signal back a change to Jiwa is that field is present or a certain value, or you could have the import into Jiwa ignore signals from the external system if such a field is present or has a certain value.


Whilst that idea is not without merit and one I had considered, unfortunately I have abandoned it given that whilst something like Salesforce which has more functionality and apis than you can climb over and will let you set conditions on whether or not it sends an out bound message, something like WooCommerce for instance only supports a webhook to the level of an entities create and update.

I am going with the idea of the lowest common denominator and the least functionality being put in external systems as possible as I want to avoid going down the rabbit hole of having to gain a level of expertise in various different platforms beyond what is necessary.

Dealing with the five different systems we represent is headache enough, particularly when two of them, one being Jiwa, given its web api and ability to add custom business objects and fields, are almost development platforms/ecosystems in their own right.

I was also thinking as a side issue the capturing of the XML could also be adapted to allow for the introduction of audit trails for Jiwa as well by grabbing the XML on a read end and then on the save end and comparing the two.
Regards
Stuart Barnes
stuart@attkey.com.au
SBarnes
Jiwa Sensei
Jiwa Sensei
 
Posts: 856
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 74

Re: Synchronising with an external system

Postby SBarnes » Sat Mar 07, 2020 2:47 pm

On doing this logging is there a way to for the save end event find an attached handler and remove it through reflection as bear in mind this won't be in the same application space that attached it?

I am trying to undo

Code: Select all
 debtor.SaveEnd += Debtor_SaveEnd;
Regards
Stuart Barnes
stuart@attkey.com.au
SBarnes
Jiwa Sensei
Jiwa Sensei
 
Posts: 856
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 74

Re: Synchronising with an external system

Postby Mike.Sheen » Sat Mar 07, 2020 4:26 pm

SBarnes wrote:On doing this logging is there a way to for the save end event find an attached handler and remove it through reflection as bear in mind this won't be in the same application space that attached it?


Reflection won't help you there if a process B wants to tell process A to stop handling the event.

You'd need to engineer a form of Inter Process Communication (IPC) to send a signal from process B to process A. You could do this by creating a socket in process A, which listens for a message and when received removes the handler. Process B would need to send a message to that socket when you want process A to remove its handler.

This is actually pretty easy to do in .NET - but you might want to make sure you don't listen to messages from strangers - a rudimentary protocol of the message containing a private key would be a good start - so reject messages without the private key present and correct.
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Jiwa Shihan
Jiwa Shihan
 
Posts: 1678
Joined: Tue Feb 12, 2008 11:12 am
Location: North Sydney
Topics Solved: 523

Re: Synchronising with an external system

Postby SBarnes » Sat Mar 07, 2020 4:35 pm

Actually I misspoke it's not a different application space I'm trying to remove the handler when the windows service logs onto Jiwa so you don't get double logging of the update you are just doing, before I've done a slight of hand where you put a flag in the in the generic object list and check that in the handler but that seems kind of kludgey.

I found the following but FieldInfo eventField = keeps coming up null, the eventinfo call work but they are pretty useless because they are related to the type rather than the instance of the object

Code: Select all
EventHandler evh = GetEventHandler(debtor, "SaveEnd");

       static EventHandler GetEventHandler(object classInstance, string eventName)
        {
            Type classType = classInstance.GetType();
           // EventInfo[] eventFields = classType.GetEvents();
           // EventInfo eventField1 = classType.GetEvent(eventName);

            FieldInfo[] fieldields =
                classType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic);

 

            FieldInfo eventField = classType.GetField(eventName, BindingFlags.GetField
                                                                 | BindingFlags.NonPublic
                                                                 | BindingFlags.Instance);

            EventHandler eventDelegate = (EventHandler)eventField.GetValue(classInstance);

            // eventDelegate will be null if no listeners are attached to the event
            if (eventDelegate == null)
            {
                return null;
            }

Regards
Stuart Barnes
stuart@attkey.com.au
SBarnes
Jiwa Sensei
Jiwa Sensei
 
Posts: 856
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 74

Re: Synchronising with an external system

Postby Mike.Sheen » Sat Mar 07, 2020 4:50 pm

StackOverflow failed me here, but I did find a post from a random blog which claims to be able to do this quite simply.

In the example they provide, it removes the Form Load handler from a windows form named "Form2" using reflection:

Code: Select all
EventInfo ei = form2.GetType().GetEvent("Load");
Delegate d = Delegate.CreateDelegate(typeof(EventHandler), form2, "Form2_Load", false);
ei.RemoveEventHandler(form2, d);


Source: c# and vb.net sample to remove eventhandler with reflection
Mike Sheen
Chief Software Engineer
Jiwa Financials

If I do answer your question to your satisfaction, please mark it as the post solving the topic so others with the same issue can readily identify the solution
User avatar
Mike.Sheen
Jiwa Shihan
Jiwa Shihan
 
Posts: 1678
Joined: Tue Feb 12, 2008 11:12 am
Location: North Sydney
Topics Solved: 523

Re: Synchronising with an external system

Postby SBarnes » Sat Mar 07, 2020 6:44 pm

It doesn't work as advertised

Code: Select all
        public void CreateDebtor()
        {
            JiwaFinancials.Jiwa.JiwaDebtors.Debtor debtor = manager.BusinessLogicFactory.CreateBusinessLogic<JiwaFinancials.Jiwa.JiwaDebtors.Debtor>(null);
            RemoveHandler(typeof(JiwaFinancials.Jiwa.JiwaApplication.IJiwaCommonInterfaces.SaveEndDelegate) ,debtor, "SaveEnd", "Debtor_SaveEnd");

        }

        public void RemoveHandler(Type delegateType, object classInstance, string eventName, string methodName)
        {
            EventInfo ei = classInstance.GetType().GetEvent(eventName);
            Delegate d = Delegate.CreateDelegate(delegateType, classInstance, methodName, false);
            ei.RemoveEventHandler(classInstance, d);

        }


produces an error of

Code: Select all
System.ArgumentException: 'Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.'


Sometimes reflection really does my head in :evil: , I think I'll go back to my generic collection flag, it may be kludgy but it works.
Regards
Stuart Barnes
stuart@attkey.com.au
SBarnes
Jiwa Sensei
Jiwa Sensei
 
Posts: 856
Joined: Fri Aug 15, 2008 3:27 pm
Topics Solved: 74


Return to Technical / Programming

Who is online

Users browsing this forum: No registered users and 27 guests

cron