Merge "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 dmaapPublisherConfig;
46     private Properties dmaapConsumerConfig;
47
48     @Autowired
49     public ApplicationConfig() {
50     }
51
52     public String getLocalConfigurationFilePath() {
53         return this.filepath;
54     }
55
56     /*
57      * Do not remove, used by framework!
58      */
59     public synchronized void setFilepath(String filepath) {
60         this.filepath = filepath;
61     }
62
63     public synchronized Collection<RicConfig> getRicConfigs() {
64         return this.ricConfigs.values();
65     }
66
67     public RicConfig getRic(String ricName) throws ServiceException {
68         for (RicConfig ricConfig : getRicConfigs()) {
69             if (ricConfig.name().equals(ricName)) {
70                 return ricConfig;
71             }
72         }
73         throw new ServiceException("Could not find ric: " + ricName);
74     }
75
76     public Properties getDmaapPublisherConfig() {
77         return dmaapConsumerConfig;
78     }
79
80     public Properties getDmaapConsumerConfig() {
81         return dmaapConsumerConfig;
82     }
83
84     public static enum RicConfigUpdate {
85         ADDED, CHANGED, REMOVED
86     }
87
88     public interface Observer {
89         void onRicConfigUpdate(RicConfig ric, RicConfigUpdate event);
90     }
91
92     public void addObserver(Observer o) {
93         this.observers.add(o);
94     }
95
96     private class Notification {
97         final RicConfig ric;
98         final RicConfigUpdate event;
99
100         Notification(RicConfig ric, RicConfigUpdate event) {
101             this.ric = ric;
102             this.event = event;
103         }
104     }
105
106     public void setConfiguration(@NotNull Collection<RicConfig> ricConfigs, Properties dmaapPublisherConfig,
107         Properties dmaapConsumerConfig) {
108         Collection<Notification> notifications = new Vector<>();
109         synchronized (this) {
110             Map<String, RicConfig> newRicConfigs = new HashMap<>();
111             for (RicConfig newConfig : ricConfigs) {
112                 RicConfig oldConfig = this.ricConfigs.get(newConfig.name());
113                 if (oldConfig == null) {
114                     newRicConfigs.put(newConfig.name(), newConfig);
115                     notifications.add(new Notification(newConfig, RicConfigUpdate.ADDED));
116                     this.ricConfigs.remove(newConfig.name());
117                 } else if (!newConfig.equals(newConfig)) {
118                     notifications.add(new Notification(newConfig, RicConfigUpdate.CHANGED));
119                     newRicConfigs.put(newConfig.name(), newConfig);
120                     this.ricConfigs.remove(newConfig.name());
121                 } else {
122                     newRicConfigs.put(oldConfig.name(), oldConfig);
123                 }
124             }
125             for (RicConfig deletedConfig : this.ricConfigs.values()) {
126                 notifications.add(new Notification(deletedConfig, RicConfigUpdate.REMOVED));
127             }
128             this.ricConfigs = newRicConfigs;
129         }
130         notifyObservers(notifications);
131
132         this.dmaapPublisherConfig = dmaapPublisherConfig;
133         this.dmaapConsumerConfig = dmaapConsumerConfig;
134     }
135
136     private void notifyObservers(Collection<Notification> notifications) {
137         for (Observer observer : this.observers) {
138             for (Notification notif : notifications) {
139                 observer.onRicConfigUpdate(notif.ric, notif.event);
140             }
141         }
142     }
143 }