565120e1d9a55cb7fbe23206c2226b6867954c66
[ccsdk/oran.git] /
1 /*-
2  * ========================LICENSE_START=================================
3  * ONAP : ccsdk oran
4  * ======================================================================
5  * Copyright (C) 2022 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
22 package org.onap.ccsdk.oran.a1policymanagementservice.datastore;
23
24 import com.google.common.base.Strings;
25
26 import java.io.File;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.lang.invoke.MethodHandles;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.stream.Stream;
35
36 import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import reactor.core.publisher.Flux;
41 import reactor.core.publisher.Mono;
42
43 class FileStore implements DataStore {
44     private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
45
46     ApplicationConfig applicationConfig;
47     private final String location;
48
49     public FileStore(ApplicationConfig applicationConfig, String location) {
50         this.applicationConfig = applicationConfig;
51         this.location = location;
52     }
53
54     @Override
55     public Flux<String> listObjects(String prefix) {
56         Path root = Path.of(path().toString(), prefix);
57         if (!root.toFile().exists()) {
58             root = root.getParent();
59         }
60
61         logger.debug("Listing files in: {}", root);
62
63         List<String> result = new ArrayList<>();
64         try (Stream<Path> stream = Files.walk(root, Integer.MAX_VALUE)) {
65
66             stream.forEach(path -> filterListFiles(path, prefix, result));
67
68             return Flux.fromIterable(result);
69         } catch (Exception e) {
70             logger.warn("Could not list filed in {}, reason; {}", root, e.getMessage());
71             return Flux.error(e);
72         }
73     }
74
75     private void filterListFiles(Path path, String prefix, List<String> result) {
76         if (path.toFile().isFile() && externalName(path).startsWith(prefix)) {
77             result.add(externalName(path));
78         } else {
79             logger.trace("Ignoring file/directory {}, prefix: {}", path, prefix);
80         }
81     }
82
83     private String externalName(Path path) {
84         String fullName = path.toString();
85         String externalName = fullName.substring(path().toString().length());
86         if (externalName.startsWith("/")) {
87             externalName = externalName.substring(1);
88         }
89         return externalName;
90     }
91
92     @Override
93     public Mono<byte[]> readObject(String fileName) {
94         try {
95             byte[] contents = Files.readAllBytes(path(fileName));
96             return Mono.just(contents);
97         } catch (Exception e) {
98             return Mono.error(e);
99         }
100     }
101
102     @Override
103     public Mono<Boolean> deleteObject(String name) {
104         try {
105             Files.delete(path(name));
106             return Mono.just(true);
107         } catch (Exception e) {
108             logger.debug("Could not delete file: {}, reason: {}", path(name), e.getMessage());
109             return Mono.just(false);
110         }
111     }
112
113     @Override
114     public Mono<String> createDataStore() {
115         try {
116             if (!Strings.isNullOrEmpty(applicationConfig.getVardataDirectory())) {
117                 Files.createDirectories(path());
118             }
119         } catch (IOException e) {
120             logger.error("Could not create directory: {}, reason: {}", path(), e.getMessage());
121         }
122         return Mono.just("OK");
123     }
124
125     private Path path(String name) {
126         return Path.of(path().toString(), name);
127     }
128
129     private Path path() {
130         return Path.of(applicationConfig.getVardataDirectory(), "database", this.location);
131     }
132
133     @Override
134     public Mono<String> deleteAllObjects() {
135         return listObjects("") //
136                 .flatMap(this::deleteObject) //
137                 .collectList() //
138                 .map(o -> "OK");
139     }
140
141     @Override
142     public Mono<byte[]> writeObject(String fileName, byte[] fileData) {
143         try {
144             if (!Strings.isNullOrEmpty(applicationConfig.getVardataDirectory())) {
145                 Files.createDirectories(path(fileName).getParent());
146             }
147             File outputFile = path(fileName).toFile();
148
149             try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
150                 outputStream.write(fileData);
151             }
152         } catch (IOException e) {
153             logger.warn("Could not write file: {}, reason; {}", path(fileName), e.getMessage());
154         }
155         return Mono.just(fileData);
156     }
157
158 }