2 * ========================LICENSE_START=================================
5 * Copyright (C) 2023 Nordix Foundation
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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===================================
21 package org.oran.pmproducer.datastore;
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;
33 import org.oran.pmproducer.configuration.ApplicationConfig;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36 import org.springframework.util.FileSystemUtils;
38 import reactor.core.publisher.Flux;
39 import reactor.core.publisher.Mono;
41 class FileStore implements DataStore {
42 private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
44 ApplicationConfig applicationConfig;
46 public FileStore(ApplicationConfig applicationConfig) {
47 this.applicationConfig = applicationConfig;
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();
57 logger.debug("Listing files in: {}", root);
59 List<String> result = new ArrayList<>();
60 try (Stream<Path> stream = Files.walk(root, Integer.MAX_VALUE)) {
62 stream.forEach(path -> filterListFiles(path, prefix, result));
64 return Flux.fromIterable(result);
65 } catch (Exception e) {
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));
74 logger.debug("Ignoring file {} that does not start with: {}", path, prefix);
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);
88 public Mono<byte[]> readObject(Bucket bucket, String fileName) {
90 byte[] contents = Files.readAllBytes(path(fileName));
91 return Mono.just(contents);
92 } catch (Exception e) {
98 public Mono<Boolean> createLock(String name) {
99 File file = path(name).toFile();
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());
111 public Mono<String> copyFileTo(Path from, String to) {
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);
123 public Mono<Boolean> deleteLock(String name) {
124 return deleteObject(Bucket.LOCKS, name);
128 public Mono<Boolean> deleteObject(Bucket bucket, String name) {
130 Files.delete(path(name));
131 return Mono.just(true);
132 } catch (Exception e) {
133 return Mono.just(false);
138 public Mono<String> create(Bucket bucket) {
139 return Mono.just("OK");
142 public Path path(String name) {
143 return Path.of(applicationConfig.getPmFilesPath(), name);
147 public Mono<String> deleteBucket(Bucket bucket) {
149 FileSystemUtils.deleteRecursively(Path.of(applicationConfig.getPmFilesPath()));
150 } catch (IOException e) {
151 logger.debug("Could not delete directory: {}, reason; {}", applicationConfig.getPmFilesPath(),
154 return Mono.just("OK");