2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2023 Nordix Foundation.
4 * Copyright (C) 2021 Nokia. All rights reserved.
5 * ================================================================================
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.oran.datafile.model;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.List;
30 import java.util.Optional;
32 import lombok.Builder;
34 import org.apache.hc.core5.http.NameValuePair;
35 import org.apache.hc.core5.net.URIBuilder;
36 import org.oran.datafile.configuration.AppConfig;
37 import org.oran.datafile.exceptions.DatafileTaskException;
38 import org.oran.datafile.model.FileServerData.FileServerDataBuilder;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * Contains data, from the fileReady event, about the file to collect from the
48 public class FileData {
51 FTPES, SFTP, HTTP, HTTPS;
53 public static final String DFC_DOES_NOT_SUPPORT_PROTOCOL_ERROR_MSG = "DFC does not support protocol ";
54 public static final String SUPPORTED_PROTOCOLS_ERROR_MESSAGE =
55 ". Supported protocols are FTPeS, sFTP, HTTP and HTTPS";
58 * Get a <code>Scheme</code> from a string.
60 * @param schemeString the string to convert to <code>Scheme</code>.
61 * @return The corresponding <code>Scheme</code>
62 * @throws DatafileTaskException if the value of the string doesn't match any
65 public static Scheme getSchemeFromString(String schemeString) throws DatafileTaskException {
67 if ("FTPES".equalsIgnoreCase(schemeString)) {
68 result = Scheme.FTPES;
69 } else if ("SFTP".equalsIgnoreCase(schemeString)) {
71 } else if ("HTTP".equalsIgnoreCase(schemeString)) {
73 } else if ("HTTPS".equalsIgnoreCase(schemeString)) {
74 result = Scheme.HTTPS;
76 throw new DatafileTaskException(
77 DFC_DOES_NOT_SUPPORT_PROTOCOL_ERROR_MSG + schemeString + SUPPORTED_PROTOCOLS_ERROR_MESSAGE);
82 public static boolean isFtpScheme(Scheme scheme) {
83 return scheme == SFTP || scheme == FTPES;
87 private static final Logger logger = LoggerFactory.getLogger(FileData.class);
89 @SuppressWarnings("java:S1104")
90 public FileReadyMessage.ArrayOfNamedHashMap fileInfo;
92 @SuppressWarnings("java:S1104")
93 public FileReadyMessage.MessageMetaData messageMetaData;
95 public static Iterable<FileData> createFileData(FileReadyMessage msg) {
96 Collection<FileData> res = new ArrayList<>();
97 for (FileReadyMessage.ArrayOfNamedHashMap arr : msg.event.notificationFields.arrayOfNamedHashMap) {
98 FileData data = FileData.builder().fileInfo(arr).messageMetaData(msg.event.commonEventHeader).build();
105 * Get the name of the PNF, must be unique in the network.
107 * @return the name of the PNF, must be unique in the network
109 public String sourceName() {
110 return messageMetaData.sourceName;
113 public String name() {
114 return this.messageMetaData.sourceName + "/" + fileInfo.name;
118 * Get the path to file to get from the PNF.
120 * @return the path to the file on the PNF.
122 public String remoteFilePath() {
123 return URI.create(fileInfo.hashMap.location).getPath();
126 public Scheme scheme() {
127 URI uri = URI.create(fileInfo.hashMap.location);
129 return Scheme.getSchemeFromString(uri.getScheme());
130 } catch (Exception e) {
131 logger.warn("Could noit get scheme :{}", e.getMessage());
137 * Get the path to the locally stored file.
139 * @return the path to the locally stored file.
141 public Path getLocalFilePath(AppConfig config) {
142 return Paths.get(config.getCollectedFilesPath(), this.messageMetaData.sourceName, fileInfo.name);
146 * Get the data about the file server where the file should be collected from.
147 * Query data included as it can contain JWT token
149 * @return the data about the file server where the file should be collected
152 public FileServerData fileServerData() {
153 URI uri = URI.create(fileInfo.hashMap.location);
154 Optional<String[]> userInfo = getUserNameAndPasswordIfGiven(uri.getUserInfo());
156 FileServerDataBuilder builder = FileServerData.builder() //
157 .serverAddress(uri.getHost()) //
158 .userId(userInfo.isPresent() ? userInfo.get()[0] : "") //
159 .password(userInfo.isPresent() ? userInfo.get()[1] : "");
160 if (uri.getPort() > 0) {
161 builder.port(uri.getPort());
163 URIBuilder uriBuilder = new URIBuilder(uri);
164 List<NameValuePair> query = uriBuilder.getQueryParams();
165 if (query != null && !query.isEmpty()) {
166 builder.queryParameters(query);
168 String fragment = uri.getRawFragment();
169 if (fragment != null && fragment.length() > 0) {
170 builder.uriRawFragment(fragment);
172 return builder.build();
176 * Extracts user name and password from the user info, if it they are given in
179 * @param userInfoString the user info string from the URI.
181 * @return An <code>Optional</code> containing a String array with the user name
182 * and password if given, or an empty
183 * <code>Optional</code> if not given.
185 private static Optional<String[]> getUserNameAndPasswordIfGiven(String userInfoString) {
186 if (userInfoString != null) {
187 String[] userAndPassword = userInfoString.split(":");
188 if (userAndPassword.length == 2) {
189 return Optional.of(userAndPassword);
190 } else if (userAndPassword.length == 1)// if just user
192 String[] tab = new String[2];
193 tab[0] = userAndPassword[0];
194 tab[1] = "";// add empty password
195 return Optional.of(tab);
198 return Optional.empty();