You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@sentry.apache.org by "Brian Towles (JIRA)" <ji...@apache.org> on 2018/08/23 16:55:00 UTC

[jira] [Comment Edited] (SENTRY-2367) Implement subsystem to allow for pluggable attribute providers and transports

    [ https://issues.apache.org/jira/browse/SENTRY-2367?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16590517#comment-16590517 ] 

Brian Towles edited comment on SENTRY-2367 at 8/23/18 4:54 PM:
---------------------------------------------------------------

This documentation is in the javadoc on the package info

 

This module is a way to simplify loading of different "plugin" service implementations within the sentry. It allows for the easy creation of separate Services and allows for multiple implementations of that service to be defined and easily loaded. It is able to get all implementations or a single one depending on configuration and need.

The Sentry API module takes advantage of the Java Service Loader which was introduced in Java 7. It uses the Factory pattern in order to get concrete instances of Services and allow for custom initialization of those concrete instances.
h3. *Create an Service Instance:*
h3. Create concert classes for the Services Provider and ProviderFactory interfaces.

In order to create a service instance you need to create instances of the services Provider and ProviderFactory interfaces. These should contain all of the necessary functions defined by the interface.

The _ProviderFactory_ instance needs to have the _getId()_ functioned defined to return a unique name for the Service Provider instance so that it can be looked up by that name.

The _create()_ function of the _ProviderFactory_ will return a concert instance of the _Provider_

{{Sample *src/main/resources/META-INF/services/org.apache.sentry.spi.FooSomeProvider* file}}
{code:java}
package org.apache.sentry.fake;
public class FooSomeProvider implements SomeProvider {
  public void doSomething(){
    ... does something ...
 }
}
{code}
{{Sample *src/main/resources/META-INF/services/org.apache.sentry.spi.FooSomeProviderFactory* file}}
{code:java}
package org.apache.sentry.fake;
public class FooSomeProviderFactory implements SomeProviderFactory {
 @Override
 public String getId() {
   return "foo"
 }
 @Override
 public SomeProvider create() {
   return new SomeProvider();
 }
}
{code}
h3. Create an entry for the _ProviderFactory_ instance in the service configuration file for the SPI

The service configuration file is placed in the *META-INF/services* directory of a jar and is named after the _ProviderFactory_ instance of the SPI.

Sample *src/main/resources/META-INF/services/org.apache.sentry.fake.SomeProviderFactory* file
{code:java}
org.apache.sentry.fake.FooSomeProviderFactory{code}
h3.  

Load the Service instance with the _ProviderManager_

You can then load the service from code with the ProviderManager. Either all service providers or an individual one.
{code:java}
# Loads instances of all SomeProviderFactory defined
 List<SomeProviderFactory> = ProviderManager.getInstance().load("some-spi");
# Loads only the "foo" instance of the SomeProviderFactory
 SomeProviderFactory someProviderFactory = ProviderManager.getInstance().load("some-spi", "foo");
{code}
h2.  

How to Implement a New Service:
h3. Create an SPI implantation

You can create Service by implementing a concrete instance of the SPI interface. This interface will provider information about what interfaces the SPI will be looking for when loading instances. It requires the Provider and the ProviderFactory information as well as a unique name for the Service in the system.

Sample *src/main/java/org/apache/sentry/fake/SomeSpi.java* file
{code:java}
package org.apache.sentry.fake;
public class SomeSpi implements Spi {
@Override
 public String getName() {
  return "some-spi";
 }
@Override
 public Class<? extends Provider> getProviderClass() {
  return SomeProvider.class;
 }
@Override
 public Class<? extends ProviderFactory> getProviderFactoryClass() {
  return SomeProviderFactory.class;
 }
}
{code}
As well you must put an entry for the SPI concrete class in the *META-INF/services/org.apache.sentry.spi.Spi* service configuration file pointing to that instance.

Sample *src/main/resources/META-INF/services/org.apache.sentry.spi.SomeSpi* file
{code:java}
org.apache.sentry.fake.SomeSpi
org.apache.sentry.fake.SomeOtherSpi{code}
h3.  

Create a the Provider and Provider Factory interfaces

You need to create the interfaces referenced in the the SPI class. These extend the Provider and ProviderFactory interfaces and can be customized to have the function definitions for how you want your service to operate.

Sample *src/main/java/org/apache/sentry/fake/SomeProvider.java* file
{code:java}
package org.apache.sentry.fake;
public interface SomeProvider extends Provider {
 void doSomething();
 }
{code}
 

Sample *src/main/java/org/apache/sentry/fake/SomeProviderFactory.java* file
{code:java}
package org.apache.sentry.fake;
public interface SomeProviderFactory extends ProviderFactory<SomeProvider> {
 void init(SomeConfig config);
}
{code}
 


was (Author: btowles):
This module is a way to simplify loading of different "plugin" service implementations within the sentry. It allows for the easy creation of separate Services and allows for multiple implementations of that service to be defined and easily loaded. It is able to get all implementations or a single one depending on configuration and need.


The Sentry API module takes advantage of the Java Service Loader which was introduced in Java 7. It uses the Factory pattern in order to get concrete instances of Services and allow for custom initialization of those concrete instances.
h3. *Create an Service Instance:*
h3. Create concert classes for the Services Provider and ProviderFactory interfaces.


In order to create a service instance you need to create instances of the services Provider and ProviderFactory interfaces. These should contain all of the necessary functions defined by the interface.


The _ProviderFactory_ instance needs to have the _getId()_ functioned defined to return a unique name for the Service Provider instance so that it can be looked up by that name.

The _create()_ function of the _ProviderFactory_ will return a concert instance of the _Provider_


{{Sample *src/main/resources/META-INF/services/org.apache.sentry.spi.FooSomeProvider* file}}
{code:java}
package org.apache.sentry.fake;
public class FooSomeProvider implements SomeProvider {
  public void doSomething(){
    ... does something ...
 }
}
{code}


{{Sample *src/main/resources/META-INF/services/org.apache.sentry.spi.FooSomeProviderFactory* file}}
{code:java}
package org.apache.sentry.fake;
public class FooSomeProviderFactory implements SomeProviderFactory {
 @Override
 public String getId() {
   return "foo"
 }
 @Override
 public SomeProvider create() {
   return new SomeProvider();
 }
}
{code}
h3. Create an entry for the _ProviderFactory_ instance in the service configuration file for the SPI


The service configuration file is placed in the *META-INF/services* directory of a jar and is named after the _ProviderFactory_ instance of the SPI.


Sample *src/main/resources/META-INF/services/org.apache.sentry.fake.SomeProviderFactory* file
{code:java}
org.apache.sentry.fake.FooSomeProviderFactory{code}
h3. 
Load the Service instance with the _ProviderManager_

You can then load the service from code with the ProviderManager. Either all service providers or an individual one.
{code:java}
# Loads instances of all SomeProviderFactory defined
 List<SomeProviderFactory> = ProviderManager.getInstance().load("some-spi");
# Loads only the "foo" instance of the SomeProviderFactory
 SomeProviderFactory someProviderFactory = ProviderManager.getInstance().load("some-spi", "foo");
{code}
h2. 
 
How to Implement a New Service:
h3. Create an SPI implantation


You can create Service by implementing a concrete instance of the SPI interface. This interface will provider information about what interfaces the SPI will be looking for when loading instances. It requires the Provider and the ProviderFactory information as well as a unique name for the Service in the system.

Sample *src/main/java/org/apache/sentry/fake/SomeSpi.java* file
{code:java}
package org.apache.sentry.fake;
public class SomeSpi implements Spi {
@Override
 public String getName() {
  return "some-spi";
 }
@Override
 public Class<? extends Provider> getProviderClass() {
  return SomeProvider.class;
 }
@Override
 public Class<? extends ProviderFactory> getProviderFactoryClass() {
  return SomeProviderFactory.class;
 }
}
{code}

 
As well you must put an entry for the SPI concrete class in the *META-INF/services/org.apache.sentry.spi.Spi* service configuration file pointing to that instance.


Sample *src/main/resources/META-INF/services/org.apache.sentry.spi.SomeSpi* file
{code:java}
org.apache.sentry.fake.SomeSpi
org.apache.sentry.fake.SomeOtherSpi{code}
h3. 
Create a the Provider and Provider Factory interfaces


You need to create the interfaces referenced in the the SPI class. These extend the Provider and ProviderFactory interfaces and can be customized to have the function definitions for how you want your service to operate.


Sample *src/main/java/org/apache/sentry/fake/SomeProvider.java* file
{code:java}
package org.apache.sentry.fake;
public interface SomeProvider extends Provider {
 void doSomething();
 }
{code}
 


Sample *src/main/java/org/apache/sentry/fake/SomeProviderFactory.java* file
 
{code:java}
package org.apache.sentry.fake;
public interface SomeProviderFactory extends ProviderFactory<SomeProvider> {
 void init(SomeConfig config);
}
{code}
 

> Implement subsystem to allow for pluggable attribute providers and transports
> -----------------------------------------------------------------------------
>
>                 Key: SENTRY-2367
>                 URL: https://issues.apache.org/jira/browse/SENTRY-2367
>             Project: Sentry
>          Issue Type: Sub-task
>          Components: Core
>    Affects Versions: 2.0.1
>            Reporter: Brian Towles
>            Assignee: Brian Towles
>            Priority: Major
>             Fix For: 2.1.0
>
>         Attachments: SENTRY-2367.001.patch
>
>
> Implement a subsystem for Sentry to for the pluggable loading of attribute providers and transports.  This will be done with the Java SPI interface and mechanisms.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)