Initial code drop of netconf protocol implementation
[controller.git] / opendaylight / netconf / config-persister-impl / src / main / java / org / opendaylight / controller / netconf / persist / impl / PersisterImpl.java
diff --git a/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterImpl.java b/opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterImpl.java
new file mode 100644 (file)
index 0000000..03892f0
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.netconf.persist.impl;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
+import org.opendaylight.controller.config.stat.ConfigProvider;
+
+import java.io.IOException;
+
+/**
+ * {@link Persister} implementation that delegates persisting functionality to
+ * underlying {@link Persister} called Storage Adapter.
+ *
+ * Storage adapters are low level persisters that do the heavy lifting for this
+ * class. Instances of storage adapters can be injected directly via constructor
+ * or instantiated from a full name of its class provided in a properties file.
+ *
+ * Name of storage adapter class should be located under
+ * {@link #STORAGE_ADAPTER_CLASS_PROP} key.
+ */
+public final class PersisterImpl implements Persister {
+
+    public static final String STORAGE_ADAPTER_CLASS_PROP = "netconf.config.persister.storageAdapterClass";
+    private final StorageAdapter storage;
+
+    public PersisterImpl(StorageAdapter storage) {
+        this.storage = storage;
+    }
+
+    public static Optional<PersisterImpl> createFromProperties(ConfigProvider configProvider) {
+        String storageAdapterClass = configProvider.getProperty(STORAGE_ADAPTER_CLASS_PROP);
+        StorageAdapter storage;
+        if (storageAdapterClass == null || storageAdapterClass.equals("")) {
+            return Optional.absent();
+        }
+
+        try {
+            storage = StorageAdapter.class.cast(resolveClass(storageAdapterClass, StorageAdapter.class).newInstance());
+            storage.setProperties(configProvider);
+
+        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            throw new IllegalArgumentException("Unable to instantiate storage adapter from " + storageAdapterClass, e);
+        }
+        return Optional.of(new PersisterImpl(storage));
+    }
+
+    private static Class<?> resolveClass(String storageAdapterClass, Class<?> baseType) throws ClassNotFoundException {
+        Class<?> clazz = Class.forName(storageAdapterClass);
+
+        if (!isImplemented(baseType, clazz))
+            throw new IllegalArgumentException("Storage adapter " + clazz + " has to implement " + baseType);
+        return clazz;
+    }
+
+    private static boolean isImplemented(Class<?> expectedIface, Class<?> byClazz) {
+        for (Class<?> iface : byClazz.getInterfaces()) {
+            if (iface.equals(expectedIface))
+                return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
+        storage.persistConfig(holder);
+    }
+
+    @Override
+    public Optional<ConfigSnapshotHolder> loadLastConfig() throws IOException {
+        return storage.loadLastConfig();
+    }
+
+    @VisibleForTesting
+    StorageAdapter getStorage() {
+        return storage;
+    }
+
+    @Override
+    public void close() throws IOException {
+        storage.close();
+    }
+
+    @Override
+    public String toString() {
+        return "PersisterImpl [storage=" + storage + "]";
+    }
+}