Repository: sentry Updated Branches: refs/heads/master d61228503 -> 2fc3374b9
SENTRY-2367: Implement subsystem to allow for pluggable attribute providers and transports (Brian Towles, reviewed Steve Moist, by Na Li) Project: http://git-wip-us.apache.org/repos/asf/sentry/repo Commit: http://git-wip-us.apache.org/repos/asf/sentry/commit/2fc3374b Tree: http://git-wip-us.apache.org/repos/asf/sentry/tree/2fc3374b Diff: http://git-wip-us.apache.org/repos/asf/sentry/diff/2fc3374b Branch: refs/heads/master Commit: 2fc3374b958c728df133befae428186d2824240e Parents: d612285 Author: lina.li <[email protected]> Authored: Fri Sep 7 16:13:14 2018 -0500 Committer: lina.li <[email protected]> Committed: Fri Sep 7 16:13:14 2018 -0500 ---------------------------------------------------------------------- pom.xml | 1 + sentry-spi/pom.xml | 56 ++++++ .../sentry/spi/DefaultProviderLoader.java | 59 +++++++ .../java/org/apache/sentry/spi/Provider.java | 37 ++++ .../org/apache/sentry/spi/ProviderFactory.java | 42 +++++ .../org/apache/sentry/spi/ProviderLoader.java | 48 +++++ .../org/apache/sentry/spi/ProviderManager.java | 109 ++++++++++++ .../main/java/org/apache/sentry/spi/Spi.java | 38 ++++ .../org/apache/sentry/spi/package-info.java | 173 +++++++++++++++++++ .../org/apache/sentry/spi/SomeTestProvider.java | 27 +++ .../sentry/spi/SomeTestProviderFactory.java | 27 +++ .../sentry/spi/SomeTestProviderImplA.java | 41 +++++ .../sentry/spi/SomeTestProviderImplB.java | 41 +++++ .../spi/SomeTestProviderImplNotLoaded.java | 41 +++++ .../java/org/apache/sentry/spi/SomeTestSpi.java | 43 +++++ .../apache/sentry/spi/TestProviderManager.java | 60 +++++++ ...rg.apache.sentry.spi.SomeTestProviderFactory | 20 +++ .../META-INF/services/org.apache.sentry.spi.Spi | 20 +++ 18 files changed, 883 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index e31c194..984e15a 100644 --- a/pom.xml +++ b/pom.xml @@ -962,6 +962,7 @@ limitations under the License. <module>sentry-tools</module> <module>sentry-service</module> <module>sentry-dist</module> + <module>sentry-spi</module> </modules> <build> http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/pom.xml ---------------------------------------------------------------------- diff --git a/sentry-spi/pom.xml b/sentry-spi/pom.xml new file mode 100644 index 0000000..f9dbc7f --- /dev/null +++ b/sentry-spi/pom.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.sentry</groupId> + <artifactId>sentry</artifactId> + <version>2.1.0-SNAPSHOT</version> + </parent> + + <artifactId>sentry-spi</artifactId> + <name>Sentry Service Provider Interface Control</name> + <version>2.1.0-SNAPSHOT</version> + + <dependencies> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/main/java/org/apache/sentry/spi/DefaultProviderLoader.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/main/java/org/apache/sentry/spi/DefaultProviderLoader.java b/sentry-spi/src/main/java/org/apache/sentry/spi/DefaultProviderLoader.java new file mode 100644 index 0000000..2d45b46 --- /dev/null +++ b/sentry-spi/src/main/java/org/apache/sentry/spi/DefaultProviderLoader.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +import java.util.LinkedList; +import java.util.List; +import java.util.ServiceLoader; + +/** + * This is the default Provider loader. It loads from the same classloader as is passed to it. + * + * This was borrowed from and inspired by the Keycloak SPI implmentation + * http://www.keycloak.org + * original Author <a href="mailto:[email protected]">Stian Thorgersen</a> + */ +public class DefaultProviderLoader implements ProviderLoader { + + private ClassLoader classLoader; + + public DefaultProviderLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public List<Spi> loadSpis() { + LinkedList<Spi> list = new LinkedList<>(); + for (Spi spi : ServiceLoader.load(Spi.class, classLoader)) { + list.add(spi); + } + return list; + } + + @Override + public List<ProviderFactory> load(Spi spi) { + LinkedList<ProviderFactory> list = new LinkedList<>(); + for (ProviderFactory f : ServiceLoader.load(spi.getProviderFactoryClass(), classLoader)) { + list.add(f); + } + return list; + } + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/main/java/org/apache/sentry/spi/Provider.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/main/java/org/apache/sentry/spi/Provider.java b/sentry-spi/src/main/java/org/apache/sentry/spi/Provider.java new file mode 100644 index 0000000..9afaed0 --- /dev/null +++ b/sentry-spi/src/main/java/org/apache/sentry/spi/Provider.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * The main Provider interface. + * + * This was borrowed from and inspired by the Keycloak SPI implmentation + * http://www.keycloak.org + * original Author <a href="mailto:[email protected]">Stian Thorgersen</a> + */ +public interface Provider { + + + default void close() { + + } + + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderFactory.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderFactory.java b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderFactory.java new file mode 100755 index 0000000..ecc8bf9 --- /dev/null +++ b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderFactory.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * This is the Factory interface for Providers to implement. Allows for custom initialization of + * Provider instances. + * Only one instance of a factory exists per server. + * + * This was borrowed from and inspired by the Keycloak SPI implmentation + * http://www.keycloak.org + * original Author <a href="mailto:[email protected]">Stian Thorgersen</a> + */ +public interface ProviderFactory<T extends Provider> { + + T create(); + + String getId(); + + default int order() { + return 0; + } + + default void close() {} +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderLoader.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderLoader.java b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderLoader.java new file mode 100644 index 0000000..eaef3e8 --- /dev/null +++ b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderLoader.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +import java.util.List; + +/** + * This is the ProviderLoader interface to allow for multiple different Provider Loading mechanics. + * + * This was borrowed from and inspired by the Keycloak SPI implmentation + * http://www.keycloak.org + * original Author <a href="mailto:[email protected]">Stian Thorgersen</a> + */ +public interface ProviderLoader { + + /** + * Load the SPI definitions themselves. + * + * @return a list of Spi definition objects + */ + List<Spi> loadSpis(); + + /** + * Load all provider factories of a specific SPI. + * + * @param spi the Spi definition + * @return a list of provider factories + */ + List<ProviderFactory> load(Spi spi); + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderManager.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderManager.java b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderManager.java new file mode 100644 index 0000000..cf48490 --- /dev/null +++ b/sentry-spi/src/main/java/org/apache/sentry/spi/ProviderManager.java @@ -0,0 +1,109 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.sentry.spi; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import java.util.Collections; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; + + + +/** + * The ProviderManager that can retrieve instances of ProviderFactory for an SPI. + * + * This was borrowed from and inspired by the Keycloak SPI implmentation + * http://www.keycloak.org + * original Author <a href="mailto:[email protected]">Stian Thorgersen</a> + * + */ +@Slf4j +public class ProviderManager { + + private static ProviderManager instance; + private Map<String, Spi> spiMap = new HashMap<>(); + private List<ProviderLoader> loaders = new LinkedList<ProviderLoader>(); + private ListMultimap<Class<? extends Provider>, ProviderFactory> cache = ArrayListMultimap + .create(); + + private ProviderManager(ClassLoader baseClassLoader) { + loaders.add(new DefaultProviderLoader(baseClassLoader)); + loadSpis(); + } + + public static ProviderManager getInstance() { + if (instance == null) { + instance = new ProviderManager(ProviderManager.class.getClassLoader()); + } + return instance; + } + + private synchronized void loadSpis() { + for (ProviderLoader loader : loaders) { + List<Spi> spis = loader.loadSpis(); + if (spis != null) { + for (Spi spi : spis) { + spiMap.put(spi.getName(), spi); + } + } + } + } + + @SuppressWarnings("unchecked") + public synchronized <T extends ProviderFactory> List<T> load(String service) { + if (!spiMap.containsKey(service)) { + throw new RuntimeException(String.format("SPI Definition for Service %s not found", service)); + } + + Spi spi = spiMap.get(service); + if (!cache.containsKey(spi.getProviderClass())) { + LOGGER.debug("Loading Service {}", spi.getName()); + IdentityHashMap factoryClasses = new IdentityHashMap(); + for (ProviderLoader loader : loaders) { + List<ProviderFactory> f = loader.load(spi); + if (f != null) { + for (ProviderFactory pf : f) { + // make sure there are no duplicates + if (!factoryClasses.containsKey(pf.getClass())) { + LOGGER.debug("Service {} provider {} loaded", spi.getName(), pf.getId()); + cache.put(spi.getProviderClass(), pf); + factoryClasses.put(pf.getClass(), pf); + } + } + } + } + } + List<T> rtn = (List<T>) cache.get(spi.getProviderClass()); + return rtn == null ? Collections.EMPTY_LIST : rtn; + } + + public synchronized <T extends ProviderFactory> T load(String service, String providerId) { + for (ProviderFactory f : load(service)) { + if (f.getId().equals(providerId)) { + return (T) f; + } + } + return null; + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/main/java/org/apache/sentry/spi/Spi.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/main/java/org/apache/sentry/spi/Spi.java b/sentry-spi/src/main/java/org/apache/sentry/spi/Spi.java new file mode 100644 index 0000000..b0ca50d --- /dev/null +++ b/sentry-spi/src/main/java/org/apache/sentry/spi/Spi.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * This is the main Service Provider Interface Definition. Custom SPIs can be implemented by + * implementing this interface and providing a reference to that implementation in the + * META-INF/service/org.apache.sentry.spi.Spi file. + * + * This was borrowed from and inspired by the Keycloak SPI implmentation + * http://www.keycloak.org + * original Author <a href="mailto:[email protected]">Stian Thorgersen</a> + */ +public interface Spi { + + String getName(); + + Class<? extends Provider> getProviderClass(); + + Class<? extends ProviderFactory> getProviderFactoryClass(); +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/main/java/org/apache/sentry/spi/package-info.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/main/java/org/apache/sentry/spi/package-info.java b/sentry-spi/src/main/java/org/apache/sentry/spi/package-info.java new file mode 100644 index 0000000..6379353 --- /dev/null +++ b/sentry-spi/src/main/java/org/apache/sentry/spi/package-info.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * <p> + * Components to implement a Service Provider Interface implementation for Sentry. + * </p> + * <p> + * These classes are a way to simplify loading of different "plugin" service implementations + * within the sentry. It allows for the easy creation of separate <strong>Services</strong> 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. + * </p> + * <p> + * The Sentry API module takes advantage of the + * <a href="https://docs.oracle.com/javase/tutorial/ext/basics/spi.html">Java Service Loader</a> + * 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. + * </p> + * + * <h2>Create an Service Instance:</h2> + * <dl> + * <dt>Create concert classes for the Services Provider and ProviderFactory interfaces.</dt> + * <dd> + * <p>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.</p> + * + * <p>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.</p> + * + * <p>The create() function of the ProviderFactory will return a concert instance of the Provider</p> + * <strong>Sample src/main/resources/META-INF/services/org.apache.sentry.spi.FooSomeProvider file</strong> + * <pre>{@code + * package org.apache.sentry.fake; + * + * public class FooSomeProvider implements SomeProvider { + * public void doSomething(){ + * ... does something ... + * } + * } + * }</pre> + * + * <strong>Sample src/main/resources/META-INF/services/org.apache.sentry.spi.FooSomeProviderFactory file</strong> + * <pre>{@code + * package org.apache.sentry.fake; + * + * public class FooSomeProviderFactory implements SomeProviderFactory { + * @Override + * public String getId() { + * return "foo" + * } + * + * @Override + * public SomeProvider create() { + * return new SomeProvider(); + * } + * } + * }</pre> + * </dd> + * <dt>Create an entry for the ProviderFactory instance in the service configuration file for + * the SPI</dt> + * <dd> + * <p>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.</p> + * <strong>Sample src/main/resources/META-INF/services/org.apache.sentry.fake.SomeProviderFactory file</strong> + * <pre>{@code + * org.apache.sentry.fake.FooSomeProviderFactory + * }</pre> + * </dd> + * <dt>Load the Service instance with the ProviderManager</dt> + * <dd> + * <p>You can then load the service from code with the ProviderManager. Either all service + * providers or an individual one.</p> + * <pre>{@code + * # 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"); + * }</pre> + * </dd> + * + * + * + * <h2>How to Implement a New Service:</h2> + * <dl> + * <dt>Create an SPI implantation</dt> + * <dd> + * <p> + * 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. + * </p> + * <strong>Sample src/main/java/org/apache/sentry/fake/SomeSpi.java file</strong> + * <pre>{@code + * 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; + * } + * } + * }</pre> + * <p> + * As well you must put an entry for the SPI concrete class in the + * <strong>META-INF/services/org.apache.sentry.spi.Spi</strong> service configuration file pointing to that instance. + * </p> + * <strong>Sample src/main/resources/META-INF/services/org.apache.sentry.spi.SomeSpi file</strong> + * <pre>{@code + * org.apache.sentry.fake.SomeSpi + * org.apache.sentry.fake.SomeOtherSpi + * }</pre> + * <dt>Create a the Provider and Provider Factory interfaces</dt> + * <dd> + * <p>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.</p> + * + * <strong>Sample rc/main/java/org/apache/sentry/fake/SomeProvider.java file</strong> + * <pre>{@code + * package org.apache.sentry.fake; + * + * public interface SomeProvider extends Provider { + * void doSomething(); + * } + * + * }</pre> + * <strong>Sample src/main/java/org/apache/sentry/fake/SomeProviderFactory.java file</strong> + * <pre>{@code + * package org.apache.sentry.fake; + * + * public interface SomeProviderFactory extends ProviderFactory<SomeProvider> { + * void init(SomeConfig config); + * } + * }</pre> + * + * </dd> + * </dl> + * + * + * + */ +package org.apache.sentry.spi; http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProvider.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProvider.java b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProvider.java new file mode 100644 index 0000000..f42e60f --- /dev/null +++ b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProvider.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * Simple Test Provider interface + */ +public interface SomeTestProvider extends Provider { + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderFactory.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderFactory.java b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderFactory.java new file mode 100644 index 0000000..a9b6967 --- /dev/null +++ b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderFactory.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * Simple Test Provider Factory Interface + */ +public interface SomeTestProviderFactory extends ProviderFactory { + +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplA.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplA.java b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplA.java new file mode 100644 index 0000000..b5599e1 --- /dev/null +++ b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplA.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * Implementation of SomeTestProvider + */ +public class SomeTestProviderImplA implements SomeTestProviderFactory, SomeTestProvider { + + @Override + public Provider create() { + return this; + } + + @Override + public String getId() { + return "A"; + } + + @Override + public void close() { + + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplB.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplB.java b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplB.java new file mode 100644 index 0000000..6291b75 --- /dev/null +++ b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplB.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * Implementation of SomeTestProvider + */ +public class SomeTestProviderImplB implements SomeTestProviderFactory, SomeTestProvider { + + @Override + public Provider create() { + return this; + } + + @Override + public String getId() { + return "B"; + } + + @Override + public void close() { + + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplNotLoaded.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplNotLoaded.java b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplNotLoaded.java new file mode 100644 index 0000000..448a59d --- /dev/null +++ b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestProviderImplNotLoaded.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * Unused Implementation of SomeTestProvider + */ +public class SomeTestProviderImplNotLoaded implements SomeTestProviderFactory, SomeTestProvider { + + @Override + public Provider create() { + return this; + } + + @Override + public String getId() { + return "NotLoaded"; + } + + @Override + public void close() { + + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestSpi.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestSpi.java b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestSpi.java new file mode 100644 index 0000000..9d3a7da --- /dev/null +++ b/sentry-spi/src/test/java/org/apache/sentry/spi/SomeTestSpi.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +/** + * Implementation of SomeTest as an SPI + */ +public class SomeTestSpi implements Spi { + + public static final String SPI = "test"; + + @Override + public String getName() { + return SPI; + } + + @Override + public Class<? extends Provider> getProviderClass() { + return SomeTestProvider.class; + } + + @Override + public Class<? extends ProviderFactory> getProviderFactoryClass() { + return SomeTestProviderFactory.class; + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/java/org/apache/sentry/spi/TestProviderManager.java ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/java/org/apache/sentry/spi/TestProviderManager.java b/sentry-spi/src/test/java/org/apache/sentry/spi/TestProviderManager.java new file mode 100644 index 0000000..b476448 --- /dev/null +++ b/sentry-spi/src/test/java/org/apache/sentry/spi/TestProviderManager.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.sentry.spi; + +import java.util.List; +import org.junit.Assert; +import org.junit.Test; + +/** + * Testing of the SPI and Provider mechanisms + */ +public class TestProviderManager { + + @Test + public void testLoadingAll() { + List<SomeTestProviderFactory> factories = ProviderManager.getInstance().load(SomeTestSpi.SPI); + Assert.assertEquals("Wrong count of service providers found", 2, factories.size()); + Assert.assertEquals("Missing instance of A", 1, + factories.stream().filter(spi -> spi instanceof SomeTestProviderImplA).count()); + Assert.assertEquals("Missing instance of B", 1, + factories.stream().filter(spi -> spi instanceof SomeTestProviderImplB).count()); + Assert.assertEquals("Instance loaded that should not be.", 0, + factories.stream().filter(spi -> spi instanceof SomeTestProviderImplNotLoaded).count()); + } + + @Test(expected = RuntimeException.class) + public void testInvalidSPI() { + ProviderManager.getInstance().load("NotThere"); + } + + @Test + public void testLoadingSingle() { + SomeTestProviderFactory factory = ProviderManager.getInstance().load(SomeTestSpi.SPI, "A"); + Assert.assertNotNull("Service provider should have been found", factory); + Assert.assertEquals("Wrong service provider loaded", "A", factory.getId()); + } + + @Test + public void testLoadingMissingSingle() { + SomeTestProviderFactory factory = ProviderManager.getInstance().load(SomeTestSpi.SPI, "Nope"); + Assert.assertNull("Service provider should not have been found", factory); + } +} http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/resources/META-INF/services/org.apache.sentry.spi.SomeTestProviderFactory ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/resources/META-INF/services/org.apache.sentry.spi.SomeTestProviderFactory b/sentry-spi/src/test/resources/META-INF/services/org.apache.sentry.spi.SomeTestProviderFactory new file mode 100644 index 0000000..bb7db3d --- /dev/null +++ b/sentry-spi/src/test/resources/META-INF/services/org.apache.sentry.spi.SomeTestProviderFactory @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +org.apache.sentry.spi.SomeTestProviderImplA +org.apache.sentry.spi.SomeTestProviderImplB \ No newline at end of file http://git-wip-us.apache.org/repos/asf/sentry/blob/2fc3374b/sentry-spi/src/test/resources/META-INF/services/org.apache.sentry.spi.Spi ---------------------------------------------------------------------- diff --git a/sentry-spi/src/test/resources/META-INF/services/org.apache.sentry.spi.Spi b/sentry-spi/src/test/resources/META-INF/services/org.apache.sentry.spi.Spi new file mode 100644 index 0000000..904f761 --- /dev/null +++ b/sentry-spi/src/test/resources/META-INF/services/org.apache.sentry.spi.Spi @@ -0,0 +1,20 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +org.apache.sentry.spi.SomeTestSpi
