a24c5bd087e3315616a36014a4cf8f9252ba307e
[ccsdk/oran.git] /
1 /*-
2  * ========================LICENSE_START=================================
3  * ONAP : ccsdk oran
4  * ======================================================================
5  * Copyright (C) 2019-2020 Nordix Foundation. 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.onap.ccsdk.oran.a1policymanagementservice.repository;
22
23 import com.google.gson.Gson;
24 import com.google.gson.GsonBuilder;
25
26 import java.io.File;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.io.PrintStream;
30 import java.lang.invoke.MethodHandles;
31 import java.nio.file.Files;
32 import java.nio.file.Path;
33 import java.time.Instant;
34 import java.util.Collection;
35 import java.util.HashMap;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.Vector;
39
40 import lombok.Builder;
41 import lombok.Getter;
42
43 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig;
44 import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.EntityNotFoundException;
45 import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.annotation.Autowired;
49 import org.springframework.context.annotation.Configuration;
50 import org.springframework.util.FileSystemUtils;
51
52 @Configuration
53 public class Policies {
54
55     @Getter
56     @Builder
57     private static class PersistentPolicyInfo {
58         private String id;
59         private String json;
60         private String ownerServiceId;
61         private String ricId;
62         private String typeId;
63         private String statusNotificationUri;
64         private boolean isTransient;
65         private String lastModified;
66     }
67
68     private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
69     private Map<String, Policy> policiesId = new HashMap<>();
70     private MultiMap<Policy> policiesRic = new MultiMap<>();
71     private MultiMap<Policy> policiesService = new MultiMap<>();
72     private MultiMap<Policy> policiesType = new MultiMap<>();
73
74     private final ApplicationConfig appConfig;
75     private static Gson gson = new GsonBuilder().create();
76
77     public Policies(@Autowired ApplicationConfig appConfig) {
78         this.appConfig = appConfig;
79     }
80
81     public synchronized void put(Policy policy) {
82         policiesId.put(policy.getId(), policy);
83         policiesRic.put(policy.getRic().id(), policy.getId(), policy);
84         policiesService.put(policy.getOwnerServiceId(), policy.getId(), policy);
85         policiesType.put(policy.getType().getId(), policy.getId(), policy);
86         if (this.appConfig.getVardataDirectory() != null && !policy.isTransient()) {
87             store(policy);
88         }
89     }
90
91     public synchronized boolean containsPolicy(String id) {
92         return policiesId.containsKey(id);
93     }
94
95     public synchronized Policy get(String id) {
96         return policiesId.get(id);
97     }
98
99     public synchronized Policy getPolicy(String id) throws EntityNotFoundException {
100         Policy p = policiesId.get(id);
101         if (p == null) {
102             throw new EntityNotFoundException("Could not find policy: " + id);
103         }
104         return p;
105     }
106
107     public synchronized Collection<Policy> getAll() {
108         return new Vector<>(policiesId.values());
109     }
110
111     public synchronized Collection<Policy> getForService(String service) {
112         return policiesService.get(service);
113     }
114
115     public synchronized Collection<Policy> getForRic(String ric) {
116         return policiesRic.get(ric);
117     }
118
119     public synchronized Collection<Policy> getForType(String type) {
120         return policiesType.get(type);
121     }
122
123     public synchronized Policy removeId(String id) {
124         Policy p = policiesId.get(id);
125         if (p != null) {
126             remove(p);
127         }
128         return p;
129     }
130
131     public synchronized void remove(Policy policy) {
132         if (!policy.isTransient()) {
133             try {
134                 Files.delete(getPath(policy));
135             } catch (IOException | ServiceException e) {
136                 logger.debug("Could not delete policy from database: {}", e.getMessage());
137             }
138         }
139         policiesId.remove(policy.getId());
140         policiesRic.remove(policy.getRic().id(), policy.getId());
141         policiesService.remove(policy.getOwnerServiceId(), policy.getId());
142         policiesType.remove(policy.getType().getId(), policy.getId());
143     }
144
145     public synchronized void removePoliciesForRic(String ricId) {
146         Collection<Policy> policiesForRic = getForRic(ricId);
147         for (Policy policy : policiesForRic) {
148             remove(policy);
149         }
150     }
151
152     public synchronized int size() {
153         return policiesId.size();
154     }
155
156     public synchronized void clear() {
157         while (policiesId.size() > 0) {
158             Set<String> keys = policiesId.keySet();
159             removeId(keys.iterator().next());
160         }
161         try {
162             if (this.appConfig.getVardataDirectory() != null) {
163                 FileSystemUtils.deleteRecursively(getDatabasePath());
164             }
165         } catch (IOException | ServiceException e) {
166             logger.warn("Could not delete policy database : {}", e.getMessage());
167         }
168     }
169
170     public void store(Policy policy) {
171         try {
172             Files.createDirectories(getDatabasePath(policy.getRic()));
173             try (PrintStream out = new PrintStream(new FileOutputStream(getFile(policy)))) {
174                 out.print(gson.toJson(toStorageObject(policy)));
175             }
176         } catch (Exception e) {
177             logger.warn("Could not store policy: {} {}", policy.getId(), e.getMessage());
178         }
179     }
180
181     private File getFile(Policy policy) throws ServiceException {
182         return getPath(policy).toFile();
183     }
184
185     private Path getPath(Policy policy) throws ServiceException {
186         return Path.of(getDatabaseDirectory(policy.getRic()), policy.getId() + ".json");
187     }
188
189     public void restoreFromDatabase(Ric ric, PolicyTypes types) {
190
191         try {
192             Files.createDirectories(getDatabasePath(ric));
193             for (File file : getDatabasePath(ric).toFile().listFiles()) {
194                 String json = Files.readString(file.toPath());
195                 PersistentPolicyInfo policyStorage = gson.fromJson(json, PersistentPolicyInfo.class);
196                 this.put(toPolicy(policyStorage, ric, types));
197             }
198         } catch (ServiceException | IOException e) {
199             logger.warn("Could not restore policy database for RIC: {}, reason : {}", ric.id(), e.getMessage());
200         }
201     }
202
203     private PersistentPolicyInfo toStorageObject(Policy p) {
204         return PersistentPolicyInfo.builder() //
205                 .id(p.getId()) //
206                 .json(p.getJson()) //
207                 .ownerServiceId(p.getOwnerServiceId()) //
208                 .ricId(p.getRic().id()) //
209                 .statusNotificationUri(p.getStatusNotificationUri()) //
210                 .typeId(p.getType().getId()) //
211                 .isTransient(p.isTransient()) //
212                 .lastModified(p.getLastModified().toString()) //
213                 .build();
214     }
215
216     Policy toPolicy(PersistentPolicyInfo p, Ric ric, PolicyTypes types) throws EntityNotFoundException {
217         return Policy.builder() //
218                 .id(p.getId()) //
219                 .isTransient(p.isTransient()) //
220                 .json(p.getJson()) //
221                 .lastModified(Instant.parse(p.lastModified)) //
222                 .ownerServiceId(p.getOwnerServiceId()) //
223                 .ric(ric) //
224                 .statusNotificationUri(p.getStatusNotificationUri()) //
225                 .type(types.getType(p.getTypeId())) //
226                 .build();
227     }
228
229     private Path getDatabasePath(Ric ric) throws ServiceException {
230         return Path.of(getDatabaseDirectory(ric));
231     }
232
233     private String getDatabaseDirectory(Ric ric) throws ServiceException {
234         return getDatabaseDirectory() + "/" + ric.id();
235     }
236
237     private String getDatabaseDirectory() throws ServiceException {
238         if (appConfig.getVardataDirectory() == null) {
239             throw new ServiceException("No database storage provided");
240         }
241         return appConfig.getVardataDirectory() + "/database/policyInstances";
242     }
243
244     private Path getDatabasePath() throws ServiceException {
245         return Path.of(getDatabaseDirectory());
246     }
247 }