Adapt A1 controller to latest A1 spec
[nonrtric.git] / policy-agent / src / main / java / org / oransc / policyagent / configuration / ApplicationConfig.java
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2019 Nordix Foundation
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.oransc.policyagent.configuration;
22
23 import java.util.Collection;
24 import java.util.HashMap;
25 import java.util.Map;
26 import java.util.Properties;
27 import java.util.Vector;
28
29 import javax.validation.constraints.NotEmpty;
30 import javax.validation.constraints.NotNull;
31
32 import org.oransc.policyagent.exceptions.ServiceException;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.boot.context.properties.ConfigurationProperties;
35 import org.springframework.boot.context.properties.EnableConfigurationProperties;
36
37 @EnableConfigurationProperties
38 @ConfigurationProperties("app")
39 public class ApplicationConfig {
40     @NotEmpty
41     private String filepath;
42
43     private Collection<Observer> observers = new Vector<>();
44     private Map<String, RicConfig> ricConfigs = new HashMap<>();
45     private Properties dmaapConsumerConfig;
46
47     @Autowired
48     public ApplicationConfig() {
49     }
50
51     public String getLocalConfigurationFilePath() {
52         return this.filepath;
53     }
54
55     /*
56      * Do not remove, used by framework!
57      */
58     public synchronized void setFilepath(String filepath) {
59         this.filepath = filepath;
60     }
61
62     public synchronized Collection<RicConfig> getRicConfigs() {
63         return this.ricConfigs.values();
64     }
65
66     public RicConfig getRic(String ricName) throws ServiceException {
67         for (RicConfig ricConfig : getRicConfigs()) {
68             if (ricConfig.name().equals(ricName)) {
69                 return ricConfig;
70             }
71         }
72         throw new ServiceException("Could not find ric: " + ricName);
73     }
74
75     public Properties getDmaapConsumerConfig() {
76         return dmaapConsumerConfig;
77     }
78
79     public static enum RicConfigUpdate {
80         ADDED, CHANGED, REMOVED
81     }
82
83     public interface Observer {
84         void onRicConfigUpdate(RicConfig ric, RicConfigUpdate event);
85     }
86
87     public void addObserver(Observer o) {
88         this.observers.add(o);
89     }
90
91     private class Notification {
92         final RicConfig ric;
93         final RicConfigUpdate event;
94
95         Notification(RicConfig ric, RicConfigUpdate event) {
96             this.ric = ric;
97             this.event = event;
98         }
99     }
100
101     public void setConfiguration(@NotNull Collection<RicConfig> ricConfigs, Properties dmaapConsumerConfig) {
102         Collection<Notification> notifications = new Vector<>();
103         synchronized (this) {
104             Map<String, RicConfig> newRicConfigs = new HashMap<>();
105             for (RicConfig newConfig : ricConfigs) {
106                 RicConfig oldConfig = this.ricConfigs.get(newConfig.name());
107                 if (oldConfig == null) {
108                     newRicConfigs.put(newConfig.name(), newConfig);
109                     notifications.add(new Notification(newConfig, RicConfigUpdate.ADDED));
110                     this.ricConfigs.remove(newConfig.name());
111                 } else if (!newConfig.equals(newConfig)) {
112                     notifications.add(new Notification(newConfig, RicConfigUpdate.CHANGED));
113                     newRicConfigs.put(newConfig.name(), newConfig);
114                     this.ricConfigs.remove(newConfig.name());
115                 } else {
116                     newRicConfigs.put(oldConfig.name(), oldConfig);
117                 }
118             }
119             for (RicConfig deletedConfig : this.ricConfigs.values()) {
120                 notifications.add(new Notification(deletedConfig, RicConfigUpdate.REMOVED));
121             }
122             this.ricConfigs = newRicConfigs;
123         }
124         notifyObservers(notifications);
125
126         this.dmaapConsumerConfig = dmaapConsumerConfig;
127     }
128
129     private void notifyObservers(Collection<Notification> notifications) {
130         for (Observer observer : this.observers) {
131             for (Notification notif : notifications) {
132                 observer.onRicConfigUpdate(notif.ric, notif.event);
133             }
134         }
135     }
136 }