Creating PM-producer
[nonrtric/plt/ranpm.git] / pmproducer / src / main / java / org / oran / pmproducer / datastore / FileStore.java
1 /*-
2  * ========================LICENSE_START=================================
3  * O-RAN-SC
4  * %%
5  * Copyright (C) 2023 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.oran.pmproducer.datastore;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.lang.invoke.MethodHandles;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.StandardCopyOption;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.stream.Stream;
32
33 import org.oran.pmproducer.configuration.ApplicationConfig;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.springframework.util.FileSystemUtils;
37
38 import reactor.core.publisher.Flux;
39 import reactor.core.publisher.Mono;
40
41 class FileStore implements DataStore {
42     private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
43
44     ApplicationConfig applicationConfig;
45
46     public FileStore(ApplicationConfig applicationConfig) {
47         this.applicationConfig = applicationConfig;
48     }
49
50     @Override
51     public Flux<String> listObjects(Bucket bucket, String prefix) {
52         Path root = Path.of(applicationConfig.getPmFilesPath(), prefix);
53         if (!root.toFile().exists()) {
54             root = root.getParent();
55         }
56
57         logger.debug("Listing files in: {}", root);
58
59         List<String> result = new ArrayList<>();
60         try (Stream<Path> stream = Files.walk(root, Integer.MAX_VALUE)) {
61
62             stream.forEach(path -> filterListFiles(path, prefix, result));
63
64             return Flux.fromIterable(result);
65         } catch (Exception e) {
66             return Flux.error(e);
67         }
68     }
69
70     private void filterListFiles(Path path, String prefix, List<String> result) {
71         if (path.toFile().isFile() && externalName(path).startsWith(prefix)) {
72             result.add(externalName(path));
73         } else {
74             logger.debug("Ignoring file {} that does not start with: {}", path, prefix);
75         }
76     }
77
78     private String externalName(Path path) {
79         String fullName = path.toString();
80         String externalName = fullName.substring(applicationConfig.getPmFilesPath().length());
81         if (externalName.startsWith("/")) {
82             externalName = externalName.substring(1);
83         }
84         return externalName;
85     }
86
87     @Override
88     public Mono<byte[]> readObject(Bucket bucket, String fileName) {
89         try {
90             byte[] contents = Files.readAllBytes(path(fileName));
91             return Mono.just(contents);
92         } catch (Exception e) {
93             return Mono.error(e);
94         }
95     }
96
97     @Override
98     public Mono<Boolean> createLock(String name) {
99         File file = path(name).toFile();
100         try {
101             Files.createDirectories(path(name).getParent());
102             boolean res = file.createNewFile();
103             return Mono.just(res);
104         } catch (Exception e) {
105             logger.warn("Could not create lock file: {}, reason: {}", file.getPath(), e.getMessage());
106             return Mono.just(!file.exists());
107         }
108     }
109
110     @Override
111     public Mono<String> copyFileTo(Path from, String to) {
112         try {
113             Path toPath = path(to);
114             Files.createDirectories(toPath);
115             Files.copy(from, path(to), StandardCopyOption.REPLACE_EXISTING);
116             return Mono.just(to);
117         } catch (Exception e) {
118             return Mono.error(e);
119         }
120     }
121
122     @Override
123     public Mono<Boolean> deleteLock(String name) {
124         return deleteObject(Bucket.LOCKS, name);
125     }
126
127     @Override
128     public Mono<Boolean> deleteObject(Bucket bucket, String name) {
129         try {
130             Files.delete(path(name));
131             return Mono.just(true);
132         } catch (Exception e) {
133             return Mono.just(false);
134         }
135     }
136
137     @Override
138     public Mono<String> create(Bucket bucket) {
139         return Mono.just("OK");
140     }
141
142     private Path path(String name) {
143         return Path.of(applicationConfig.getPmFilesPath(), name);
144     }
145
146     @Override
147     public Mono<String> deleteBucket(Bucket bucket) {
148         try {
149             FileSystemUtils.deleteRecursively(Path.of(applicationConfig.getPmFilesPath()));
150         } catch (IOException e) {
151             logger.debug("Could not delete directory: {}, reason; {}", applicationConfig.getPmFilesPath(),
152                     e.getMessage());
153         }
154         return Mono.just("OK");
155     }
156
157 }