aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory')
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/api/AbstractFactory.java81
-rw-r--r--openecomp-be/lib/openecomp-core-lib/openecomp-facade-lib/openecomp-facade-api/src/main/java/org/openecomp/core/factory/impl/AbstractFactoryBase.java212
2 files changed, 293 insertions, 0 deletions
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&lt;IUnknown&gt;
+ * ^
+ * |
+ * 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&lt;IUnknown&gt; {
+ * static {
+ * registerFactory(ConcreteFactory.class, BaselineFactoryImpl.class);
+ * }
+ * public static ConcreteFactory getInstance() {
+ * return AbstractFactory.&lt;IUnknown, ConcreteFactory.class&gt;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() {
+ }
+
+}