e4d55d11fb39e126d2dbb99f0ceb0cb6672d7069
[controller.git] / opendaylight / configuration / implementation / src / main / java / org / opendaylight / controller / configuration / internal / ConfigurationService.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.configuration.internal;
11
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.EnumSet;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Set;
18 import java.util.concurrent.ConcurrentMap;
19
20 import org.opendaylight.controller.clustering.services.CacheConfigException;
21 import org.opendaylight.controller.clustering.services.CacheExistException;
22 import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
23 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
24 import org.opendaylight.controller.clustering.services.IClusterServices;
25 import org.opendaylight.controller.configuration.ConfigurationEvent;
26 import org.opendaylight.controller.configuration.ConfigurationObject;
27 import org.opendaylight.controller.configuration.IConfigurationAware;
28 import org.opendaylight.controller.configuration.IConfigurationService;
29 import org.opendaylight.controller.sal.utils.GlobalConstants;
30 import org.opendaylight.controller.sal.utils.IObjectReader;
31 import org.opendaylight.controller.sal.utils.ObjectReader;
32 import org.opendaylight.controller.sal.utils.ObjectWriter;
33 import org.opendaylight.controller.sal.utils.Status;
34 import org.opendaylight.controller.sal.utils.StatusCode;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 /**
39  * @file   ConfigurationImpl.java
40  *
41  * @brief  Backend functionality for all ConfigurationService related tasks.
42  *
43  */
44
45 public class ConfigurationService implements IConfigurationService, ICacheUpdateAware<ConfigurationEvent, String> {
46     private static final Logger logger = LoggerFactory
47             .getLogger(ConfigurationService.class);
48     public static final String SAVE_EVENT_CACHE = "config.event.save";
49     private static final Object ROOT = GlobalConstants.STARTUPHOME.toString();
50     private IClusterGlobalServices clusterServices;
51     private ConcurrentMap <ConfigurationEvent, String> configEvent;
52     private Set<IConfigurationAware> configurationAwareList = Collections
53             .synchronizedSet(new HashSet<IConfigurationAware>());
54     private ObjectReader objReader;
55     private ObjectWriter objWriter;
56
57
58     public int getConfigurationAwareListSize() {
59         return this.configurationAwareList.size();
60     }
61
62     public void addConfigurationAware(IConfigurationAware configurationAware) {
63         if (!this.configurationAwareList.contains(configurationAware)) {
64             this.configurationAwareList.add(configurationAware);
65         }
66     }
67
68     public void removeConfigurationAware(IConfigurationAware configurationAware) {
69         this.configurationAwareList.remove(configurationAware);
70     }
71
72     public void setClusterServices(IClusterGlobalServices i) {
73         this.clusterServices = i;
74         logger.debug("IClusterServices set");
75     }
76
77     public void unsetClusterServices(IClusterGlobalServices i) {
78         if (this.clusterServices == i) {
79             this.clusterServices = null;
80             logger.debug("IClusterServices Unset");
81         }
82     }
83
84     public void init() {
85         logger.info("ConfigurationService Manager init");
86     }
87
88     public void start() {
89         allocateCache();
90         retrieveCache();
91         objReader = new ObjectReader();
92         objWriter = new ObjectWriter();
93     }
94
95     public void destroy() {
96         // Clear local states
97         this.configurationAwareList.clear();
98     }
99
100     @Override
101     public Status saveConfigurations() {
102         if (configEvent != null) {
103             configEvent.put(ConfigurationEvent.SAVE, "");
104         }
105         return saveConfigurationsInternal();
106     }
107
108     private Status saveConfigurationsInternal() {
109         boolean success = true;
110         for (IConfigurationAware configurationAware : configurationAwareList) {
111             Status status = configurationAware.saveConfiguration();
112             if (!status.isSuccess()) {
113                 success = false;
114                 logger.warn("Failed to save config for {}",
115                         configurationAware.getClass().getName());
116             }
117         }
118         if (success) {
119             return new Status(StatusCode.SUCCESS);
120         } else {
121             return new Status(StatusCode.INTERNALERROR,
122                     "Failed to Save All Configurations");
123         }
124     }
125
126     @Override
127     public void entryCreated(ConfigurationEvent key, String cacheName,
128             boolean originLocal) {
129         if (originLocal) {
130             return;
131         }
132     }
133
134     @Override
135     public void entryUpdated(ConfigurationEvent key, String new_value,
136             String cacheName, boolean originLocal) {
137         if (originLocal) {
138             return;
139         }
140         if (key == ConfigurationEvent.SAVE) {
141             saveConfigurationsInternal();
142         }
143     }
144
145     @Override
146     public void entryDeleted(ConfigurationEvent key, String cacheName,
147             boolean originLocal) {
148         if (originLocal) {
149             return;
150         }
151     }
152
153     private void allocateCache() {
154         if (this.clusterServices == null) {
155             logger.error("uninitialized clusterServices, can't create cache");
156             return;
157         }
158         try {
159             this.clusterServices.createCache(SAVE_EVENT_CACHE,
160                     EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
161         } catch (CacheConfigException cce) {
162             logger.debug("Error creating ConfigurationService cache ", cce);
163         } catch (CacheExistException cce) {
164             logger.debug("ConfigurationService Cache already exists, destroy and recreate ", cce);
165         }
166     }
167
168     @SuppressWarnings({ "unchecked" })
169     private void retrieveCache() {
170         if (this.clusterServices == null) {
171             logger.error("uninitialized clusterServices, can't retrieve cache");
172             return;
173         }
174         configEvent = (ConcurrentMap<ConfigurationEvent, String>) this.clusterServices.getCache(SAVE_EVENT_CACHE);
175         if (configEvent == null) {
176             logger.error("Failed to retrieve configuration Cache");
177         }
178     }
179
180     @Override
181     public Status persistConfiguration(List<ConfigurationObject> config, String fileName) {
182         String destination = String.format("%s%s", ROOT, fileName);
183         return objWriter.write(config, destination);
184     }
185
186     @Override
187     public List<ConfigurationObject> retrieveConfiguration(IObjectReader reader, String fileName) {
188         if (!clusterServices.amICoordinator()) {
189             return Collections.emptyList();
190         }
191         String source = String.format("%s%s", ROOT, fileName);
192         Object obj = objReader.read(reader, source);
193         if (obj == null) {
194             return Collections.<ConfigurationObject> emptyList();
195         }
196         if (obj instanceof ConcurrentMap) {
197             return new ArrayList<ConfigurationObject>(((ConcurrentMap)obj).values());
198         }
199         return (List<ConfigurationObject>) obj;
200     }
201 }