Configuration file runtime reload
[sdc.git] / common-app-api / src / main / java / org / openecomp / sdc / common / impl / ConfigFileChangeListener.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.sdc.common.impl;
22
23 import java.io.File;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import org.apache.commons.collections.CollectionUtils;
29 import org.apache.commons.jci.listeners.FileChangeListener;
30 import org.openecomp.sdc.common.api.BasicConfiguration;
31 import org.openecomp.sdc.common.api.ConfigurationListener;
32 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
33 import org.openecomp.sdc.common.log.wrappers.Logger;
34 import org.openecomp.sdc.common.util.YamlToObjectConverter;
35 import org.openecomp.sdc.exception.YamlConversionException;
36
37 public class ConfigFileChangeListener extends FileChangeListener {
38
39         private static final Logger LOGGER = Logger.getLogger(ConfigFileChangeListener.class.getName());
40
41         private Map<String, List<ConfigurationListener>> fileChangeToCallBack = new HashMap<>();
42
43         private Object lock = new Object();
44
45         private YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter();
46
47         @Override
48         public void onFileChange(File pFile) {
49                 super.onFileChange(pFile);
50
51                 if (pFile == null) {
52                         LOGGER.debug("Invalid file '{}'.", pFile);
53                         return;
54                 }
55
56                 if (fileChangeToCallBack == null) {
57                         LOGGER.debug("File '{}' callback is null.", pFile);
58                         return;
59                 }
60
61                 final String id = findIdFromFileName(pFile.getName());
62                 if (id == null) {
63                         LOGGER.warn(EcompLoggerErrorCode.UNKNOWN_ERROR,"","",
64                                 "Cannot calculate id from file {}", pFile.getName());
65                         return;
66                 }
67
68                 final List<ConfigurationListener> listeners = fileChangeToCallBack.get(id);
69                 if (CollectionUtils.isEmpty(listeners)) {
70                         LOGGER.debug("No file listeners for file '{}', id '{}'.", pFile, id);
71                         return;
72                 }
73                 for (final ConfigurationListener configurationListener : listeners) {
74                         final Class<? extends BasicConfiguration> configClass = configurationListener.getType();
75                         final BasicConfiguration basicConfiguration;
76                         try {
77                                 basicConfiguration = yamlToObjectConverter.convert(pFile.getAbsolutePath(), configClass);
78                         } catch (final YamlConversionException e) {
79                                 LOGGER.warn(EcompLoggerErrorCode.SCHEMA_ERROR,
80                                         "Configuration", "Configuration",
81                                         "Cannot update the listeners for file Change since the file content is invalid: {}",
82                                         e.getLocalizedMessage());
83                                 continue;
84                         }
85                         LOGGER.debug("Loaded configuration after converting is {}", basicConfiguration);
86                         configurationListener.getCallBack().reconfigure(basicConfiguration);
87                 }
88                 LOGGER.debug("File {} was changed.", pFile);
89         }
90
91         private String findIdFromFileName(String name) {
92
93                 String result = null;
94                 if (name != null) {
95                         int startIndex = 0;
96                         int endIndex = name.length();
97                         if (name.contains(File.separator)) {
98                                 startIndex = name.lastIndexOf(File.separator);
99                         }
100
101                         result = name.substring(startIndex, endIndex);
102
103                 }
104
105                 return result;
106         }
107
108         public void register(String id, ConfigurationListener configurationListener) {
109
110                 if (configurationListener != null) {
111
112                         synchronized (lock) {
113
114                                 List<ConfigurationListener> callbacks = fileChangeToCallBack.get(id);
115                                 if (callbacks == null) {
116                                         callbacks = new ArrayList<>();
117                                         fileChangeToCallBack.put(id, callbacks);
118                                 }
119                                 callbacks.add(configurationListener);
120
121                         }
122
123                 }
124
125         }
126
127 }