[
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)