/*- * ============LICENSE_START======================================================= * Copyright (C) 2019-2023 Nordix Foundation. * Copyright (C) 2021 Nokia. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ package org.oran.datafile.model; import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Optional; import lombok.Builder; import org.apache.hc.core5.http.NameValuePair; import org.apache.hc.core5.net.URIBuilder; import org.oran.datafile.configuration.AppConfig; import org.oran.datafile.exceptions.DatafileTaskException; import org.oran.datafile.model.FileServerData.FileServerDataBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Contains data, from the fileReady event, about the file to collect from the * xNF. * */ @Builder public class FileData { public enum Scheme { FTPES, SFTP, HTTP, HTTPS; public static final String DFC_DOES_NOT_SUPPORT_PROTOCOL_ERROR_MSG = "DFC does not support protocol "; public static final String SUPPORTED_PROTOCOLS_ERROR_MESSAGE = ". Supported protocols are FTPeS, sFTP, HTTP and HTTPS"; /** * Get a Scheme from a string. * * @param schemeString the string to convert to Scheme. * @return The corresponding Scheme * @throws DatafileTaskException if the value of the string doesn't match any * defined scheme. */ public static Scheme getSchemeFromString(String schemeString) throws DatafileTaskException { Scheme result; if ("FTPES".equalsIgnoreCase(schemeString)) { result = Scheme.FTPES; } else if ("SFTP".equalsIgnoreCase(schemeString)) { result = Scheme.SFTP; } else if ("HTTP".equalsIgnoreCase(schemeString)) { result = Scheme.HTTP; } else if ("HTTPS".equalsIgnoreCase(schemeString)) { result = Scheme.HTTPS; } else { throw new DatafileTaskException( DFC_DOES_NOT_SUPPORT_PROTOCOL_ERROR_MSG + schemeString + SUPPORTED_PROTOCOLS_ERROR_MESSAGE); } return result; } public static boolean isFtpScheme(Scheme scheme) { return scheme == SFTP || scheme == FTPES; } } private static final Logger logger = LoggerFactory.getLogger(FileData.class); @SuppressWarnings("java:S1104") public FileReadyMessage.ArrayOfNamedHashMap fileInfo; @SuppressWarnings("java:S1104") public FileReadyMessage.MessageMetaData messageMetaData; public static Iterable createFileData(FileReadyMessage msg) { Collection res = new ArrayList<>(); for (FileReadyMessage.ArrayOfNamedHashMap arr : msg.event.notificationFields.arrayOfNamedHashMap) { FileData data = FileData.builder().fileInfo(arr).messageMetaData(msg.event.commonEventHeader).build(); res.add(data); } return res; } /** * Get the name of the PNF, must be unique in the network. * * @return the name of the PNF, must be unique in the network */ public String sourceName() { return messageMetaData.sourceName; } public String name() { return this.messageMetaData.sourceName + "/" + fileInfo.name; } /** * Get the path to file to get from the PNF. * * @return the path to the file on the PNF. */ public String remoteFilePath() { return URI.create(fileInfo.hashMap.location).getPath(); } public Scheme scheme() { URI uri = URI.create(fileInfo.hashMap.location); try { return Scheme.getSchemeFromString(uri.getScheme()); } catch (Exception e) { logger.warn("Could noit get scheme :{}", e.getMessage()); return Scheme.FTPES; } } /** * Get the path to the locally stored file. * * @return the path to the locally stored file. */ public Path getLocalFilePath(AppConfig config) { return Paths.get(config.getCollectedFilesPath(), this.messageMetaData.sourceName, fileInfo.name); } /** * Get the data about the file server where the file should be collected from. * Query data included as it can contain JWT token * * @return the data about the file server where the file should be collected * from. */ public FileServerData fileServerData() { URI uri = URI.create(fileInfo.hashMap.location); Optional userInfo = getUserNameAndPasswordIfGiven(uri.getUserInfo()); FileServerDataBuilder builder = FileServerData.builder() // .serverAddress(uri.getHost()) // .userId(userInfo.isPresent() ? userInfo.get()[0] : "") // .password(userInfo.isPresent() ? userInfo.get()[1] : ""); if (uri.getPort() > 0) { builder.port(uri.getPort()); } URIBuilder uriBuilder = new URIBuilder(uri); List query = uriBuilder.getQueryParams(); if (query != null && !query.isEmpty()) { builder.queryParameters(query); } String fragment = uri.getRawFragment(); if (fragment != null && fragment.length() > 0) { builder.uriRawFragment(fragment); } return builder.build(); } /** * Extracts user name and password from the user info, if it they are given in * the URI. * * @param userInfoString the user info string from the URI. * * @return An Optional containing a String array with the user name * and password if given, or an empty * Optional if not given. */ private static Optional getUserNameAndPasswordIfGiven(String userInfoString) { if (userInfoString != null) { String[] userAndPassword = userInfoString.split(":"); if (userAndPassword.length == 2) { return Optional.of(userAndPassword); } else if (userAndPassword.length == 1)// if just user { String[] tab = new String[2]; tab[0] = userAndPassword[0]; tab[1] = "";// add empty password return Optional.of(tab); } } return Optional.empty(); } }