diff options
Diffstat (limited to 'openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api')
3 files changed, 324 insertions, 0 deletions
diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/pom.xml b/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/pom.xml new file mode 100644 index 0000000000..ccb3db833e --- /dev/null +++ b/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/pom.xml @@ -0,0 +1,31 @@ +<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.openecomp.sdc</groupId> + <artifactId>openecomp-sdc-lib</artifactId> + <version>1.0.0-SNAPSHOT</version> + <relativePath>../../..</relativePath> + </parent> + + <name>openecomp-facade-api</name> + <artifactId>openecomp-facade-api</artifactId> + <groupId>org.openecomp.core</groupId> + + + <dependencies> + + <dependency> + <groupId>org.openecomp.core</groupId> + <artifactId>openecomp-utilities-lib</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.core</groupId> + <artifactId>openecomp-common-lib</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + +</project>
\ No newline at end of file diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/api/AbstractFactory.java b/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/api/AbstractFactory.java new file mode 100644 index 0000000000..53b8f00fc0 --- /dev/null +++ b/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/api/AbstractFactory.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.core.factory.api; + +import org.openecomp.core.factory.impl.AbstractFactoryBase; + +/** + * This class provides generic implementation of an abstract factory. Components exposed as Java + * interfaces should have their own concrete factories derived from the given class. This assures + * code alignment and consistency across all Service Management components. + * The class actually + * uses singleton pattern to instantiate and reuse just one instance of a factory. Therefore, each + * factory implementation has to be <i>thread-safe</i>. + * In a general case, the hierarchy of + * factory objects for an Java interface <tt>IUknown</tt> may look as follows: + * <pre> + * AbstractFactory<IUnknown> + * ^ + * | + * Application code ----> ConcreteFactory + * ^ + * | + * +---------+---------+ + * | | + * BaselineFactoryImpl CustomFactoryImpl + * </pre> + * Where the classes responsibility is: <ul> <li>Abstract factory - common logic to retrieve the + * implementation class name from a central repository.</li> <li>Concrete factory - abstract class + * that only exposes to application layer the type specific API such as: <ul> <li><tt>public static + * ConcreteFactory getInstance()</tt></li> </ul> <li>Baseline factory - out of the box + * implementation of concrete factory (that can be replaced by a custom one depending on customer + * needs) which actually implements method: <ul> <li><tt>public IUnknown createInterface()</tt></li> + * </ul> </ul> The normal concrete factory class may look like: + * <pre> + * public abstract class ConcreteFactory extends AbstractFactory<IUnknown> { + * static { + * registerFactory(ConcreteFactory.class, BaselineFactoryImpl.class); + * } + * public static ConcreteFactory getInstance() { + * return AbstractFactory.<IUnknown, ConcreteFactory.class>getInstance(ConcreteFactory.class); + * } + * } + * </pre> + * + * @param <I> Java interface type created by the factory. + */ +public abstract class AbstractFactory<I> extends AbstractFactoryBase { + + + /** + * Returns the interface implementor instance. + * <b>Note</b>: It's up to the concrete factory to decide on the actual + * implementation of the returned interface. Therefore, the call can get the + * same instance per each call in case of singleton implementation or new + * instance otherwise. However, the API consumer may not assume anything + * regarding the underlying logic and has always go through the factory to + * obtain the reference. + * + * @return Implementor of the exposed Java interface. + */ + public abstract I createInterface(); + +} // End of class diff --git a/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/impl/AbstractFactoryBase.java b/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/impl/AbstractFactoryBase.java new file mode 100644 index 0000000000..e19d9e972f --- /dev/null +++ b/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/impl/AbstractFactoryBase.java @@ -0,0 +1,212 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.core.factory.impl; + +import static org.openecomp.core.utilities.CommonMethods.isEmpty; +import static org.openecomp.core.utilities.CommonMethods.newInstance; + +import org.openecomp.sdc.common.errors.CoreException; +import org.openecomp.sdc.common.errors.ErrorCategory; +import org.openecomp.sdc.common.errors.ErrorCode; + + +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * The type Abstract factory base. + */ +public abstract class AbstractFactoryBase { + + /** + * Temporary registry of default implementations. The map keeps class names rather then class + * types to allow unloading of those classes from memory by garbage collector if + * factory is not actually used. + */ + private static Map<String, String> registry = new ConcurrentHashMap<String, String>(); + + /** + * Cached factory instances. + */ + private static Map<String, AbstractFactoryBase> factoryMap = + new ConcurrentHashMap<String, AbstractFactoryBase>(); + + /** + * Registers implementor for an abstract factory. The method accepts Java classes rather + * then class names to ensure type safety at compilation time. + * + * @param <I> Java interface type instantiated by abstract factory + * @param <F> Type specific abstract factory for concrete Java interface + * @param factory Java class of a type specific abstract factory + * @param impl Java class of type specific factory implementor + */ + public static <I, F extends AbstractFactoryBase> void registerFactory(Class<F> factory, + Class<? extends F> impl) { + if (factory == null) { + throw new CoreException( + new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input factory.") + .withCategory(ErrorCategory.SYSTEM).build()); + } + + if (impl == null) { + throw new CoreException( + new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input impl.") + .withCategory(ErrorCategory.SYSTEM).build()); + } + if (factoryMap != null && factoryMap.containsKey(factory.getName())) { + factoryMap.remove(factory.getName()); + } + registry.put(factory.getName(), impl.getName()); + } // registerFactory + + /** + * Register factory. + * + * @param factoryName the factory name + * @param implName the impl name + */ + // TODO: Remove + protected static void registerFactory(String factoryName, String implName) { + registry.put(factoryName, implName); + } // registerFactory + + /** + * Unregister factory. + * + * @param <F> the type parameter + * @param factory the factory + */ + public static <F extends AbstractFactoryBase> void unregisterFactory(Class<F> factory) { + if (factory == null) { + throw new CoreException( + new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input factory.") + .withCategory(ErrorCategory.SYSTEM).build()); + } + if (factoryMap != null) { + factoryMap.remove(factory.getName()); + } + } + + /** + * Instantiates the configured implementation of an abstract factory. + * + * @param <I> Java interface type instantiated by abstract factory + * @param <F> Type specific abstract factory for concrete Java interface + * @param factoryType Java class of type specific abstract factory + * @return Instance of implementation class + */ + @SuppressWarnings("unchecked") + public static <I, F extends AbstractFactoryBase> F getInstance(Class<F> factoryType) { + if (factoryType == null) { + throw new CoreException( + new ErrorCode.ErrorCodeBuilder().withId("E0001") + .withMessage("Mandatory input factory type.").withCategory(ErrorCategory.SYSTEM) + .build()); + + } + // Pick up factory instance from cache + F factory = (F) factoryMap.get(factoryType.getName()); + // Check for the first time access + if (factory == null) { + // Synchronize factory instantiation + synchronized (factoryType) { + // Re-check the factory instance + factory = (F) factoryMap.get(factoryType.getName()); + if (factory == null) { + // Get the implementation class name + String implName = registry.get(factoryType.getName()); + + if (isEmpty(implName)) { + throw new CoreException( + new ErrorCode.ErrorCodeBuilder().withId("E0001") + .withMessage("Mandatory input factory implementation.") + .withCategory(ErrorCategory.SYSTEM).build()); + } + + factory = newInstance(implName, factoryType); + + factory.init(); + + // Cache the instantiated singleton + factoryMap.put(factoryType.getName(), factory); + } + } + } + + return factory; + + } // getInstance + + + /** + * Is factory registered boolean. + * + * @param <F> the type parameter + * @param factoryType the factory type + * @return the boolean + */ + public static <F extends AbstractFactoryBase> boolean isFactoryRegistered(Class<F> factoryType) { + boolean isFactoryRegistered = false; + if (factoryType == null) { + throw new CoreException( + new ErrorCode.ErrorCodeBuilder().withId("E0001") + .withMessage("Mandatory input factory type.").withCategory(ErrorCategory.SYSTEM) + .build()); + } + // Pick up factory instance from cache + F factory = (F) factoryMap.get(factoryType.getName()); + // Check for the first time access + if (factory != null) { + isFactoryRegistered = true; + } else { + // Get the implementation class name + String implName = registry.get(factoryType.getName()); + if (!isEmpty(implName)) { + isFactoryRegistered = true; + } + } + return isFactoryRegistered; + } + + /** + * Stop all. + */ + public static void stopAll() { + Collection<AbstractFactoryBase> factorylist = factoryMap.values(); + for (AbstractFactoryBase factory : factorylist) { + factory.stop(); + } + } + + /** + * Init. + */ + protected void init() { + } + + /** + * Stop. + */ + protected void stop() { + } + +} |