21#include <Poco/Net/AcceptCertificateHandler.h>
22#include <Poco/Net/HTTPRequest.h>
23#include <Poco/Net/HTTPResponse.h>
24#include <Poco/Net/HTTPSClientSession.h>
25#include <Poco/Net/PrivateKeyPassphraseHandler.h>
26#include <Poco/Net/SSLException.h>
27#include <Poco/Net/SSLManager.h>
28#include <Poco/Net/SecureStreamSocket.h>
29#include <Poco/StreamCopier.h>
38using namespace Kernel;
46 "List of fileids to download from the data server");
48 "List of filenames to download from the data server");
49 declareProperty(
"DownloadPath",
"",
"The path to save the downloaded files.");
50 declareProperty(
"Session",
"",
"The session information of the catalog to use.");
53 "A list of file locations to the catalog datafiles.");
59 auto catalogInfoService = std::dynamic_pointer_cast<API::ICatalogInfoService>(
62 if (!catalogInfoService)
63 throw std::runtime_error(
"The catalog that you are using does not support "
64 "external downloading.");
67 UserCatalogInfo catalogInfo(ConfigService::Instance().getFacility().catalogInfo(), *catConfigService);
69 std::vector<int64_t> fileIDs =
getProperty(
"FileIds");
70 std::vector<std::string> fileNames =
getProperty(
"FileNames");
75 std::vector<std::string> fileLocations;
79 std::vector<int64_t>::const_iterator fileID = fileIDs.begin();
80 std::vector<std::string>::const_iterator fileName = fileNames.begin();
83 for (; fileID != fileIDs.end(); ++fileID, ++fileName) {
85 double prog =
m_prog / (double(fileIDs.size()) / 10);
87 progress(prog,
"getting location string...");
90 std::string fileLocation = catalogInfoService->getFileLocation(*fileID);
92 g_log.
debug() <<
"CatalogDownloadDataFiles -> File location before transform is: " << fileLocation
93 <<
" mac path is : " << catalogInfo.
macPrefix() <<
'\n';
96 g_log.
debug() <<
"CatalogDownloadDataFiles -> File location after transform is: " << fileLocation <<
'\n';
99 std::ifstream hasAccessToArchives(fileLocation.c_str());
100 if (hasAccessToArchives) {
101 g_log.
information() <<
"File (" << *fileName <<
") located in archives (" << fileLocation <<
").\n";
102 fileLocations.emplace_back(fileLocation);
105 <<
") from archive. Beginning to download over Internet.\n";
106 progress(prog / 2,
"getting the url ....");
108 const std::string url = catalogInfoService->getDownloadURL(*fileID);
109 progress(prog,
"downloading over internet...");
111 fileLocations.emplace_back(fullPathDownloadedFile);
125 std::filesystem::path path(fileName);
126 std::string extension = path.extension().string();
127 if (!extension.empty() && extension[0] ==
'.') {
128 extension = extension.substr(1);
130 std::transform(extension.begin(), extension.end(), extension.begin(), tolower);
131 return (extension ==
"raw" || extension ==
"nxs");
142 const std::string &fileName) {
143 std::string pathToDownloadedDatafile;
148 std::string path(uri.getPathAndQuery());
149 clock_t start = clock();
151 Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> certificateHandler =
152 new Poco::Net::AcceptCertificateHandler(
true);
155 const Poco::Net::Context::Ptr context =
156 new Poco::Net::Context(Poco::Net::Context::CLIENT_USE,
"",
"",
"", Poco::Net::Context::VERIFY_NONE);
159 Poco::Net::SSLManager::instance().initializeClient(
nullptr, certificateHandler, context);
162 Poco::Net::SecureStreamSocket socket{context};
163 Poco::Net::HTTPSClientSession session{socket, uri.getHost(), uri.getPort()};
165 Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
166 session.sendRequest(request);
169 Poco::Net::HTTPResponse response;
171 std::istream &responseStream = session.receiveResponse(response);
174 Poco::Net::HTTPResponse::HTTPStatus HTTPStatus = response.getStatus();
178 if (!IDSError.empty()) {
189 pathToDownloadedDatafile =
saveFiletoDisk(responseStream, fileName);
191 clock_t end = clock();
192 float diff = float(end - start) / CLOCKS_PER_SEC;
193 g_log.
information() <<
"Time taken to download file " << fileName <<
" is " << std::fixed << std::setprecision(2)
194 << diff <<
" seconds\n";
196 }
catch (Poco::Net::SSLException &
error) {
197 throw std::runtime_error(
error.displayText());
206 catch (Poco::Exception &
error) {
207 throw std::runtime_error(
error.displayText());
210 return pathToDownloadedDatafile;
222 std::filesystem::path filepath = downloadPath / fileName;
223 std::ios_base::openmode mode =
isDataFile(fileName) ? std::ios_base::binary : std::ios_base::out;
225 std::ofstream ofs(filepath, mode);
226 if (ofs.rdstate() & std::ios::failbit)
229 Poco::StreamCopier::copyStream(rs, ofs);
231 return filepath.string();
#define DECLARE_ALGORITHM(classname)
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
void cancel() override
Raises the cancel flag.
const std::string getIDSError(const Poco::Net::HTTPResponse::HTTPStatus &HTTPStatus, std::istream &responseStream)
Obtain the error message returned by the IDS.
CatalogDownloadDataFiles is responsible for downloading datafiles from a catalog.
double m_prog
progress indicator
std::string testDownload(const std::string &URL, const std::string &fileName)
This method is used for unit testing purpose.
std::string doDownloadandSavetoLocalDrive(const std::string &URL, const std::string &fileName)
Saves downloaded file to local disk.
std::string saveFiletoDisk(std::istream &rs, const std::string &fileName)
Saves the downloaded file to disc.
bool isDataFile(const std::string &fileName)
True if the extension of the file is a datafile.
void exec() override
Overwrites Algorithm method.
Support for a property that holds an array of values.
Records the filename and the description of failure.
virtual std::string transformArchivePath(const std::string &path) const
Transform's the archive path based on operating system used.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void information(const std::string &msg)
Logs at information level.
UserCatalogInfo : Takes catalog info from the facility (via CatalogInfo), but provides the ability to...
const std::string macPrefix() const override
Obtain Macintosh prefix from facility file.
CatalogConfigService * makeCatalogConfigServiceAdapter(const T &adaptee, const std::string &key="icatDownload.mountPoint")
@ Output
An output workspace.