4b013be96accd7d22eb5f83704437f4c1b641606
[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     public FileReadyMessage.ArrayOfNamedHashMap fileInfo;
90
91     public FileReadyMessage.MessageMetaData messageMetaData;
92
93     public static Iterable<FileData> createFileData(FileReadyMessage msg) {
94         Collection<FileData> res = new ArrayList<>();
95         for (FileReadyMessage.ArrayOfNamedHashMap arr : msg.event.notificationFields.arrayOfNamedHashMap) {
96             FileData data = FileData.builder().fileInfo(arr).messageMetaData(msg.event.commonEventHeader).build();
97             res.add(data);
98         }
99         return res;
100     }
101
102     /**
103      * Get the name of the PNF, must be unique in the network.
104      *
105      * @return the name of the PNF, must be unique in the network
106      */
107     public String sourceName() {
108         return messageMetaData.sourceName;
109     }
110
111     public String name() {
112         return this.messageMetaData.sourceName + "/" + fileInfo.name;
113     }
114
115     /**
116      * Get the path to file to get from the PNF.
117      *
118      * @return the path to the file on the PNF.
119      */
120     public String remoteFilePath() {
121         return URI.create(fileInfo.hashMap.location).getPath();
122     }
123
124     public Scheme scheme() {
125         URI uri = URI.create(fileInfo.hashMap.location);
126         try {
127             return Scheme.getSchemeFromString(uri.getScheme());
128         } catch (Exception e) {
129             logger.warn("Could noit get scheme :{}", e.getMessage());
130             return Scheme.FTPES;
131         }
132     }
133
134     /**
135      * Get the path to the locally stored file.
136      *
137      * @return the path to the locally stored file.
138      */
139     public Path getLocalFilePath(AppConfig config) {
140         return Paths.get(config.getCollectedFilesPath(), this.messageMetaData.sourceName, fileInfo.name);
141     }
142
143     /**
144      * Get the data about the file server where the file should be collected from.
145      * Query data included as it can contain JWT token
146      *
147      * @return the data about the file server where the file should be collected
148      *         from.
149      */
150     public FileServerData fileServerData() {
151         URI uri = URI.create(fileInfo.hashMap.location);
152         Optional<String[]> userInfo = getUserNameAndPasswordIfGiven(uri.getUserInfo());
153
154         FileServerDataBuilder builder = FileServerData.builder() //
155             .serverAddress(uri.getHost()) //
156             .userId(userInfo.isPresent() ? userInfo.get()[0] : "") //
157             .password(userInfo.isPresent() ? userInfo.get()[1] : "");
158         if (uri.getPort() > 0) {
159             builder.port(uri.getPort());
160         }
161         URIBuilder uriBuilder = new URIBuilder(uri);
162         List<NameValuePair> query = uriBuilder.getQueryParams();
163         if (query != null && !query.isEmpty()) {
164             builder.queryParameters(query);
165         }
166         String fragment = uri.getRawFragment();
167         if (fragment != null && fragment.length() > 0) {
168             builder.uriRawFragment(fragment);
169         }
170         return builder.build();
171     }
172
173     /**
174      * Extracts user name and password from the user info, if it they are given in
175      * the URI.
176      *
177      * @param userInfoString the user info string from the URI.
178      *
179      * @return An <code>Optional</code> containing a String array with the user name
180      *         and password if given, or an empty
181      *         <code>Optional</code> if not given.
182      */
183     private static Optional<String[]> getUserNameAndPasswordIfGiven(String userInfoString) {
184         if (userInfoString != null) {
185             String[] userAndPassword = userInfoString.split(":");
186             if (userAndPassword.length == 2) {
187                 return Optional.of(userAndPassword);
188             } else if (userAndPassword.length == 1)// if just user
189             {
190                 String[] tab = new String[2];
191                 tab[0] = userAndPassword[0];
192                 tab[1] = "";// add empty password
193                 return Optional.of(tab);
194             }
195         }
196         return Optional.empty();
197     }
198 }