c2a93cc61f35fe731356359de261847e792dadd6
[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.util.ArrayList;
34 import java.util.Collection;
35 import java.util.HashMap;
36 import java.util.Map;
37 import java.util.Vector;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40
41 import org.jetbrains.annotations.Nullable;
42 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig;
43 import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.EntityNotFoundException;
44 import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47 import org.springframework.beans.factory.annotation.Autowired;
48 import org.springframework.context.annotation.Configuration;
49 import org.springframework.util.FileSystemUtils;
50
51 @Configuration
52 public class PolicyTypes {
53     private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
54     private Map<String, PolicyType> types = new HashMap<>();
55     private final ApplicationConfig appConfig;
56     private static Gson gson = new GsonBuilder().create();
57
58     public PolicyTypes(@Autowired ApplicationConfig appConfig) {
59         this.appConfig = appConfig;
60         restoreFromDatabase();
61     }
62
63     public synchronized PolicyType getType(String name) throws EntityNotFoundException {
64         PolicyType t = types.get(name);
65         if (t == null) {
66             throw new EntityNotFoundException("Could not find type: " + name);
67         }
68         return t;
69     }
70
71     public synchronized PolicyType get(String name) {
72         return types.get(name);
73     }
74
75     public synchronized void put(PolicyType type) {
76         types.put(type.getId(), type);
77         store(type);
78     }
79
80     public synchronized boolean contains(String policyType) {
81         return types.containsKey(policyType);
82     }
83
84     public synchronized Collection<PolicyType> getAll() {
85         return new Vector<>(types.values());
86     }
87
88     /**
89      * Filter out types matching criterias
90      *
91      * @param types the types to select from
92      * @param typeName select types with given type name
93      * @param regexp select types where the ID matches a regular
94      *        expression
95      * @param compatibleWithVersion select types that are compatible with given
96      *        version string (major.minor.patch)
97      * @return the types that matches given criterias
98      * @throws ServiceException if there are errors in the given input
99      */
100     public static Collection<PolicyType> filterTypes(Collection<PolicyType> types, @Nullable String typeName,
101             @Nullable String regexp, @Nullable String compatibleWithVersion) throws ServiceException {
102         if (typeName != null) {
103             types = filterTypeName(types, typeName);
104         }
105         if (regexp != null) {
106             types = filterRegexp(types, regexp);
107         }
108         if (compatibleWithVersion != null) {
109             types = filterCompatibleWithVersion(types, compatibleWithVersion);
110         }
111         return types;
112     }
113
114     public synchronized int size() {
115         return types.size();
116     }
117
118     public synchronized void clear() {
119         this.types.clear();
120         try {
121             FileSystemUtils.deleteRecursively(getDatabasePath());
122         } catch (IOException | ServiceException e) {
123             logger.warn("Could not delete policy type database : {}", e.getMessage());
124         }
125     }
126
127     public void store(PolicyType type) {
128         try {
129             Files.createDirectories(getDatabasePath());
130             try (PrintStream out = new PrintStream(new FileOutputStream(getFile(type)))) {
131                 out.print(gson.toJson(type));
132             }
133         } catch (ServiceException e) {
134             logger.debug("Could not store policy type: {} {}", type.getId(), e.getMessage());
135         } catch (IOException e) {
136             logger.warn("Could not store policy type: {} {}", type.getId(), e.getMessage());
137         }
138     }
139
140     private File getFile(PolicyType type) throws ServiceException {
141         return Path.of(getDatabaseDirectory(), type.getId() + ".json").toFile();
142     }
143
144     void restoreFromDatabase() {
145         try {
146             Files.createDirectories(getDatabasePath());
147             for (File file : getDatabasePath().toFile().listFiles()) {
148                 String json = Files.readString(file.toPath());
149                 PolicyType type = gson.fromJson(json, PolicyType.class);
150                 this.types.put(type.getId(), type);
151             }
152             logger.debug("Restored type database,no of types: {}", this.types.size());
153         } catch (ServiceException e) {
154             logger.debug("Could not restore policy type database : {}", e.getMessage());
155         } catch (Exception e) {
156             logger.warn("Could not restore policy type database : {}", e.getMessage());
157         }
158     }
159
160     private String getDatabaseDirectory() throws ServiceException {
161         if (appConfig.getVardataDirectory() == null) {
162             throw new ServiceException("No policy type storage provided");
163         }
164         return appConfig.getVardataDirectory() + "/database/policyTypes";
165     }
166
167     private Path getDatabasePath() throws ServiceException {
168         return Path.of(getDatabaseDirectory());
169     }
170
171     private static Collection<PolicyType> filterRegexp(Collection<PolicyType> types, String regexp) {
172         Collection<PolicyType> result = new ArrayList<>();
173         Pattern pattern = Pattern.compile(regexp);
174         for (PolicyType type : types) {
175             Matcher matcher = pattern.matcher(type.getId());
176             if (matcher.find()) {
177                 result.add(type);
178             }
179         }
180         return result;
181     }
182
183     private static Collection<PolicyType> filterTypeName(Collection<PolicyType> types, String typeName) {
184         Collection<PolicyType> result = new ArrayList<>();
185         for (PolicyType type : types) {
186             PolicyType.TypeId nameVersion = type.getTypeId();
187             if (nameVersion.getName().equals(typeName)) {
188                 result.add(type);
189             }
190         }
191         return result;
192     }
193
194     private static boolean isTypeCompatibleWithVersion(PolicyType type, PolicyType.Version version) {
195         try {
196             PolicyType.TypeId typeId = type.getTypeId();
197             PolicyType.Version typeVersion = PolicyType.Version.ofString(typeId.getVersion());
198             return (typeVersion.major == version.major && typeVersion.minor >= version.minor);
199         } catch (Exception e) {
200             logger.warn("Ignoring type with syntactically incorrect type ID: {}", type.getId());
201             return false;
202         }
203     }
204
205     private static Collection<PolicyType> filterCompatibleWithVersion(Collection<PolicyType> types, String versionStr)
206             throws ServiceException {
207         Collection<PolicyType> result = new ArrayList<>();
208         PolicyType.Version otherVersion = PolicyType.Version.ofString(versionStr);
209         for (PolicyType type : types) {
210             if (isTypeCompatibleWithVersion(type, otherVersion)) {
211                 result.add(type);
212             }
213         }
214         return result;
215     }
216
217 }