Add running configuration data to get netconf operation response
[controller.git] / opendaylight / netconf / config-persister-impl / src / main / java / org / opendaylight / controller / netconf / persist / impl / PersisterImpl.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.netconf.persist.impl;
10
11 import com.google.common.annotations.VisibleForTesting;
12 import com.google.common.base.Optional;
13 import org.opendaylight.controller.config.persist.api.Persister;
14 import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
15 import org.osgi.framework.BundleContext;
16
17 import java.io.IOException;
18
19 /**
20  * {@link Persister} implementation that delegates persisting functionality to
21  * underlying {@link Persister} called Storage Adapter.
22  *
23  * Storage adapters are low level persisters that do the heavy lifting for this
24  * class. Instances of storage adapters can be injected directly via constructor
25  * or instantiated from a full name of its class provided in a properties file.
26  *
27  * Name of storage adapter class should be located under
28  * {@link #STORAGE_ADAPTER_CLASS_PROP} key.
29  */
30 public final class PersisterImpl implements Persister {
31
32     public static final String STORAGE_ADAPTER_CLASS_PROP = "netconf.config.persister.storageAdapterClass";
33     private final StorageAdapter storage;
34
35     public PersisterImpl(StorageAdapter storage) {
36         this.storage = storage;
37     }
38
39     public static Optional<PersisterImpl> createFromProperties(BundleContext bundleContext) {
40         String storageAdapterClass = bundleContext.getProperty(STORAGE_ADAPTER_CLASS_PROP);
41         StorageAdapter storage;
42         if (storageAdapterClass == null || storageAdapterClass.equals("")) {
43             return Optional.absent();
44         }
45
46         try {
47             storage = StorageAdapter.class.cast(resolveClass(storageAdapterClass, StorageAdapter.class).newInstance());
48             storage.setProperties(bundleContext);
49
50         } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
51             throw new IllegalArgumentException("Unable to instantiate storage adapter from " + storageAdapterClass, e);
52         }
53         return Optional.of(new PersisterImpl(storage));
54     }
55
56     private static Class<?> resolveClass(String storageAdapterClass, Class<?> baseType) throws ClassNotFoundException {
57         Class<?> clazz = Class.forName(storageAdapterClass);
58
59         if (!isImplemented(baseType, clazz))
60             throw new IllegalArgumentException("Storage adapter " + clazz + " has to implement " + baseType);
61         return clazz;
62     }
63
64     private static boolean isImplemented(Class<?> expectedIface, Class<?> byClazz) {
65         for (Class<?> iface : byClazz.getInterfaces()) {
66             if (iface.equals(expectedIface))
67                 return true;
68         }
69         return false;
70     }
71
72     @Override
73     public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
74         storage.persistConfig(holder);
75     }
76
77     @Override
78     public Optional<ConfigSnapshotHolder> loadLastConfig() throws IOException {
79         return storage.loadLastConfig();
80     }
81
82     @VisibleForTesting
83     StorageAdapter getStorage() {
84         return storage;
85     }
86
87     @Override
88     public void close() throws IOException {
89         storage.close();
90     }
91
92     @Override
93     public String toString() {
94         return "PersisterImpl [storage=" + storage + "]";
95     }
96 }