Improve Test coverage of DFC
[nonrtric/plt/ranpm.git] / datafilecollector / src / main / java / org / oran / datafile / model / FileData.java
1 /*-
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.oran.datafile.model;
23
24 import java.net.URI;
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;
31
32 import lombok.Builder;
33
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;
41
42 /**
43  * Contains data, from the fileReady event, about the file to collect from the
44  * xNF.
45  *
46  */
47 @Builder
48 public class FileData {
49
50     public enum Scheme {
51         FTPES, SFTP, HTTP, HTTPS;
52
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";
56
57         /**
58          * Get a <code>Scheme</code> from a string.
59          *
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
63          *         defined scheme.
64          */
65         public static Scheme getSchemeFromString(String schemeString) throws DatafileTaskException {
66             Scheme result;
67             if ("FTPES".equalsIgnoreCase(schemeString)) {
68                 result = Scheme.FTPES;
69             } else if ("SFTP".equalsIgnoreCase(schemeString)) {
70                 result = Scheme.SFTP;
71             } else if ("HTTP".equalsIgnoreCase(schemeString)) {
72                 result = Scheme.HTTP;
73             } else if ("HTTPS".equalsIgnoreCase(schemeString)) {
74                 result = Scheme.HTTPS;
75             } else {
76                 throw new DatafileTaskException(
77                     DFC_DOES_NOT_SUPPORT_PROTOCOL_ERROR_MSG + schemeString + SUPPORTED_PROTOCOLS_ERROR_MESSAGE);
78             }
79             return result;
80         }
81
82         public static boolean isFtpScheme(Scheme scheme) {
83             return scheme == SFTP || scheme == FTPES;
84         }
85     }
86
87     private static final Logger logger = LoggerFactory.getLogger(FileData.class);
88
89     @SuppressWarnings("java:S1104")
90     public FileReadyMessage.ArrayOfNamedHashMap fileInfo;
91
92     @SuppressWarnings("java:S1104")
93     public FileReadyMessage.MessageMetaData messageMetaData;
94
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();
99             res.add(data);
100         }
101         return res;
102     }
103
104     /**
105      * Get the name of the PNF, must be unique in the network.
106      *
107      * @return the name of the PNF, must be unique in the network
108      */
109     public String sourceName() {
110         return messageMetaData.sourceName;
111     }
112
113     public String name() {
114         return this.messageMetaData.sourceName + "/" + fileInfo.name;
115     }
116
117     /**
118      * Get the path to file to get from the PNF.
119      *
120      * @return the path to the file on the PNF.
121      */
122     public String remoteFilePath() {
123         return URI.create(fileInfo.hashMap.location).getPath();
124     }
125
126     public Scheme scheme() {
127         URI uri = URI.create(fileInfo.hashMap.location);
128         try {
129             return Scheme.getSchemeFromString(uri.getScheme());
130         } catch (Exception e) {
131             logger.warn("Could noit get scheme :{}", e.getMessage());
132             return Scheme.FTPES;
133         }
134     }
135
136     /**
137      * Get the path to the locally stored file.
138      *
139      * @return the path to the locally stored file.
140      */
141     public Path getLocalFilePath(AppConfig config) {
142         return Paths.get(config.getCollectedFilesPath(), this.messageMetaData.sourceName, fileInfo.name);
143     }
144
145     /**
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
148      *
149      * @return the data about the file server where the file should be collected
150      *         from.
151      */
152     public FileServerData fileServerData() {
153         URI uri = URI.create(fileInfo.hashMap.location);
154         Optional<String[]> userInfo = getUserNameAndPasswordIfGiven(uri.getUserInfo());
155
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());
162         }
163         URIBuilder uriBuilder = new URIBuilder(uri);
164         List<NameValuePair> query = uriBuilder.getQueryParams();
165         if (query != null && !query.isEmpty()) {
166             builder.queryParameters(query);
167         }
168         String fragment = uri.getRawFragment();
169         if (fragment != null && fragment.length() > 0) {
170             builder.uriRawFragment(fragment);
171         }
172         return builder.build();
173     }
174
175     /**
176      * Extracts user name and password from the user info, if it they are given in
177      * the URI.
178      *
179      * @param userInfoString the user info string from the URI.
180      *
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.
184      */
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
191             {
192                 String[] tab = new String[2];
193                 tab[0] = userAndPassword[0];
194                 tab[1] = "";// add empty password
195                 return Optional.of(tab);
196             }
197         }
198         return Optional.empty();
199     }
200 }