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 <[email protected]> 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 <[email protected]> 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) > >
