osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discussion] Fineract CN SMS & Email Notifications Project


Wow! the reason for Anubis is deep. I should have consulted you for
suggestions.

First of all apologies for the 404s. I clean up my repo ( squashed some
commits and deleted a few test branches) and so I had to force push to my
git repo when I wanted to pull onto the VM. All the new code on the
authentication is here
https://github.com/ebenezergraham/fineract-cn-notifications/tree/permitted-feign-client-auth.
I will be mindful of squash and force push next time.

Wada means "To be loved".The notification service is my first ever open
source project and as a wannabe open source advocate this was a really big
deal for me hence *"my love for it".* Also partly because it's an
Indigenous Kalanga name, I am fascinated by southern African languages and
as such, I leave a trail of it on significant things in my life. :)

But after reading the meaning of Anubis. I guess *hermes* would be a
perfect name. One of the twelve Olympian gods ( mostly known as the
messenger god). :0

Currently, wrapping my head around the explanation given. I will try to
understand it and get back to you.

*At your service,*

*Ebenezer Graham*

*BSc (Hons) Computing*


[image: EmailSignature.png]

African Leadership University,

Power Mill Road, Pamplemousses,

Mauritius.


*skype*:
ebenezer.graham
GitHub <https://github.com/ebenezergraham> | LinkedIn
<https://www.linkedin.com/in/ebenezer-graham/> | Twitter
<https://twitter.com/pactmart> | Facebook
<https://www.facebook.com/pactmart>
www.pactmart.com | Freelancing made easy.


*“Talk is cheap, show me the code.” *- *Linus Torvalds*




On Mon, 8 Oct 2018 at 23:01, Myrle Krantz <myrle@xxxxxxxxxx> wrote:

> Hey Ebenezer,
> those code
> First the easy question:
> The services do all have code names, which we use to name the tables.
> Most of them are named after Egyptian gods.  Anubis for example plays
> a part in the judgement of the newly dead, and so it seemed
> appropriate that the library responsible for authentication and
> authorization at the service level should also be called anubis.
> There's a Maat's feather in there somewhere too.
>
> I'm glad you picked a code name for notifications too.  I bellieve it
> actually makes communication about the services more precise, and it's
> also fun.
>
> Does "wada" mean anything?
>
> Unfortunately the code links you included don't work (I'm getting
> 404's).  But I took a look through your repositories as they are in
> github anyways.  And it seems likely that you haven't understood how
> this works yet.  Which is understandable since it is complex and
> poorly documented.
>
> The current best I have available is here, but this may be confusing
> because the interaction being prepared is with identity, in addition
> to identity's involvement with the provisioning of permissions:
>
> https://cwiki.apache.org/confluence/display/FINERACT/Fineract+CN+demo-server
>  (In other words identity is involved in two parts of that problem
> instead of just one, and that muddies the waters.)
>
> Let me take another swing at it.  I'm currently assuming the only
> function you need from customer is CustomerManager.findCustomer.  That
> function is in the permittable group customer__v1__customer.  Here's
> what will need to happen and how your code fits in.  I've put stars
> next to the parts which will require you to do something.  I'll
> explain below what you need to do for each star.  Some of it you are
> already doing, so you can take those stars home : o)
>
> demo_server -> provisioner: add customer service to the tenant
> (skipping some parts here)
>   provisioner -> customer: ask what permissions are part of customer
>   provisioner -> identity: create the permission groups which are part
> of customer, including the permittable group customer__v1__customer.
> demo_server -> identity: create the role notificationAdmin, set it to
> include permissions to the parts of customer you want to access. *1
> demo_server -> identity: add user wadaadmin with the role
> notificationAdmin. *2
> demo_server -> provisioner: add wada service to the tenant *3
>   provisioner -> wada: provision signature with same timestamp as
> current identity signature.
>   provisioner -> identity: create application with signature returned by
> wada
>   provisioner -> wada: ask what permissions wada needs.  Wada responds
> that it needs customer__v1__customer. *4
>   provisioner -> identity: create permission request for wada to
> access customer to get customer information.
>   provisioner -> wada: initialize tenant data tables in separate database.
> *5
> demo_server -> identity: allow wada to call customer__v1__customer as
> wadaadmin. *6
>
> *1.  You are already doing this in the demo-server function
> ServiceRunner::defineNotificationRole
> *2.  You are already doing this in the demo-server function
> ServiceRunner::createNotificationsAdmin
> *3.  You are already doing this in the demo-server function
> ServiceRunner::provisionAppsViaSeshat
> *4.  This is done by creating a feign interface for customer within
> the notification service code.  You can find an example in rhythm
> under ApplicationPermissionRequestCreator, intended to make it
> possible for rhythm to access identity.  In your case though you want
> wada to access customer, so you'll create a class that looks something
> like this:
>
> @EndpointSet(identifier = "notificiations__v1__customer__v1")
> @FeignClient(name="customer-v1", path="/customer/v1",
> configuration=PermittedFeignClientsConfiguration.class)
> public interface ApplicationPermissionRequestCreator {
>   @RequestMapping(...) /* copy params from CustomerManager */
>   @ThrowsException(...)/* copy params from CustomerManager */
>   @Permittable(groupId =
> org.apache.fineract.cn.customer.PermittableGroupIds.CUSTOMER)
>   Customer findCustomer(...); /* copy params from CustomerManager */
> }
>
> *5.  You are already doing this in notifications function
> MigrationAggregate::provisionAppsViaSeshatForTenant with a call to
> provisionApp for notificationManager.
> *6.  After all the other pieces are in place, login as wadaadmin and
> call.  This won't work until after notificationManager is provisioned.
> identityManager.api().setApplicationPermissionEnabledForUser(
>         notificationManager.name(),
>         org.apache.fineract.cn.customer.PermittableGroupIds.CUSTOMER,
>         notificationsAdminUser.getIdentifier(),
>         true);
>
> If you still can't figure it out after this, I'd like to puzzle
> together with you.  Write me an e-mail and we'll set up a pair
> programming session, and then bring back anything we learn to the
> list.
>
> Best Regards,
> Myrle Krantz
>
> On Mon, Oct 8, 2018 at 12:21 AM Ebenezer Graham
> <egraham15@xxxxxxxxxxxxxx> wrote:
> >
> > HI Myrle,
> >
> > I will try this approach to connect to the VM. Thanks.
> >
> > Yes you are right, this happens during provisioning of the services
> >
> > This is the line throwing the exception
> >
> https://github.com/ebenezergraham/fineract-cn-demo-server/blob/application-permission-for-notification/
> > src/main/java/org/apache/fineract/cn/dev/ServiceRunner.java#L451
> > This is where I attempt to setApplicationPermissionEnabledForUser.
> >
> > I attempted to create the application request here:
> >
> https://github.com/ebenezergraham/fineract-cn-demo-server/blob/application-permission-for-notification/src/main/java/org/apache/fineract/cn/dev/ServiceRunner.java#L484-#L514
> >
> >
> > ** at provisioning, service A tells provisioner about its
> > permissiongroups.  provisioner then tells identity.*
> >
> > And so I understand this mechanism correctly, for the notification
> service
> > to be able to read data from the customer service a permission group has
> to
> > be defined in customer.
> >
> > Please correct me if I am wrong, this is done by declaring a groupId in
> the
> > PermittableGroupIds interface in customer(eg:
> > notification__v1__customer__v1?) and under the hood, provisioner will set
> > that in identity.
> >
> >
> > ** The demo-server than creates a user (Fred?) which which has accessto
> > that permission group.*
> > In other not create new users ( as this caused problems for other
> > developers) I believe I can use scheduler just like rhythm?
> >
> > I have added permission to read from a customer during the creation of
> the
> > scheduler
> >
> https://github.com/ebenezergraham/fineract-cn-demo-server/blob/application-permission-for-notification/src/main/java/org/apache/fineract/cn/dev/ServiceRunner.java#L588-#L590
> >
> >
> >
> > ** Then when service B is being provisioned, it tells identity aboutthe
> > permission groups that it will need in service A.*
> > So I believe the start fails because notification is setting a permission
> > which doesn't exist (customer never informed identity through
> provisioner).
> >
> >
> > ** The demo-server, in the name of Fred, gives service B permission
> tocall
> > service A on that permission group as Fred.*
> >
> > Also, I saw that other services have code names from the documentation.
> And
> > so I gave the notification service the name wada. I used it to prefix the
> > database tables. Is it alright to give it a code name? :)
> >
> > *At your service,*
> >
> > *Ebenezer Graham*
> >
> > *BSc (Hons) Computing*
> >
> >
> > [image: EmailSignature.png]
> >
> > African Leadership University,
> >
> > Power Mill Road, Pamplemousses,
> >
> > Mauritius.
> >
> >
> > *skype*:
> > ebenezer.graham
> > GitHub <https://github.com/ebenezergraham> | LinkedIn
> > <https://www.linkedin.com/in/ebenezer-graham/> | Twitter
> > <https://twitter.com/pactmart> | Facebook
> > <https://www.facebook.com/pactmart>
> > www.pactmart.com | Freelancing made easy.
> >
> >
> > *“Talk is cheap, show me the code.” *- *Linus Torvalds*
> >
> >
> >
> >
> > On Mon, 8 Oct 2018 at 01:08, Myrle Krantz <myrle@xxxxxxxxxx> wrote:
> >
> > > Hey Ebenezer,
> > >
> > > I've never debugged a process on a remote server, but it should be
> > > possible.  First you'll need to find out what port debugging is
> > > running on and open that port.
> > >
> > > Aside from that, I've included the text you linked to in pastebin
> > > below (for snippets this short it's easier on me if you just include
> > > them in the mail.)
> > >
> > > It seems like your problem is actually in the start up of demo-server,
> > > is that correct?  But what line number?  What call is producing this
> > > exception?
> > >
> > > I can explain a bit about the permission requesting mechanism in
> > > identity.  If service B needs to call service A, then the following
> > > happens:
> > > * at provisioning, service A tells provisioner about its permission
> > > groups.  provisioner then tells identity.
> > > * The demo-server than creates a user (Fred?) which which has access
> > > to that permission group.
> > > * Then when service B is being provisioned, it tells identity about
> > > the permission groups that it will need in service A.
> > > * The demo-server, in the name of Fred, gives service B permission to
> > > call service A on that permission group as Fred.
> > >
> > > This line looks like you're expecting a permission group in customer
> > > called wada.  There is no such permission group.  Are you trying to
> > > get information from customer?  Is that why you need this permission?
> > > You'll need to call identity.setApplicationPermissionEnabledForUser.
> > >
> > > Can you share the code throwing this exception?  It would make things
> > > much easier.
> > >
> > > Best Regards,
> > > Myrle
> > >
> > >
> > > 1) startDevServer(org.apache.fineract.cn.dev.ServiceRunner)
> > > org.apache.fineract.cn.api.util.NotFoundException:
> > > {"timestamp":1538925629122,"status":404,"error":"Not
> > >
> > >
> Found","exception":"org.apache.fineract.cn.lang.ServiceException","message":"Application
> > > permission 'notification-v1.customer__v1__wada' doesn't
> > >
> > >
> exist.","path":"/identity/v1/applications/notification-v1/permissions/customer__v1__wada/users/imhotep/enabled"}
> > > at
> > >
> org.apache.fineract.cn.api.util.AnnotatedErrorDecoder.getAlternative(AnnotatedErrorDecoder.java:76)
> > > at
> > >
> org.apache.fineract.cn.api.util.AnnotatedErrorDecoder.decode(AnnotatedErrorDecoder.java:65)
> > > at
> > >
> feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138)
> > > at
> feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
> > > at
> > >
> feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
> > > at
> com.sun.proxy.$Proxy207.setApplicationPermissionEnabledForUser(Unknown
> > > Source)
> > > at
> > >
> org.apache.fineract.cn.dev.ServiceRunner.provisionAppsViaSeshatForTenant(ServiceRunner.java:451)
> > > at
> > >
> org.apache.fineract.cn.dev.ServiceRunner.provisionAppsViaSeshat(ServiceRunner.java:359)
> > > at
> > >
> org.apache.fineract.cn.dev.ServiceRunner.startDevServer(ServiceRunner.java:257)
> > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > > at
> > >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> > > at
> > >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> > > at java.lang.reflect.Method.invoke(Method.java:498)
> > > at
> > >
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
> > > at
> > >
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
> > > at
> > >
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
> > > at
> > >
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
> > > at
> > >
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
> > > at
> > >
> org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
> > > at
> > >
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
> > > at
> > >
> org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
> > > at
> > >
> org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
> > > at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
> > > at
> > >
> org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
> > > at
> > >
> org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
> > > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
> > > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
> > > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
> > > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
> > > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
> > > at
> > >
> org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
> > > at
> > >
> org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
> > > at
> org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
> > > at
> org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
> > > at
> org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
> > > at org.junit.rules.RunRules.evaluate(RunRules.java:20)
> > > at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
> > > at
> > >
> org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
> > > at org.junit.runners.Suite.runChild(Suite.java:128)
> > > at org.junit.runners.Suite.runChild(Suite.java:27)
> > > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
> > > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
> > > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
> > > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
> > > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
> > > at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
> > > at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
> > > at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
> > > at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77)
> > > at org.junit.runner.JUnitCore.main(JUnitCore.java:36)
> > > at org.apache.fineract.cn.dev.DemoServer.main(DemoServer.java:30)
> > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > > at
> > >
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> > > at
> > >
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> > > at java.lang.reflect.Method.invoke(Method.java:498)
> > > at
> > >
> org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
> > > at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
> > > at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
> > > at
> org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:58)
> > >
>