20#include <Poco/Net/AcceptCertificateHandler.h>
21#include <Poco/Net/HTTPRequest.h>
22#include <Poco/Net/HTTPResponse.h>
23#include <Poco/Net/HTTPSClientSession.h>
24#include <Poco/Net/PrivateKeyPassphraseHandler.h>
25#include <Poco/Net/SSLException.h>
26#include <Poco/Net/SSLManager.h>
27#include <Poco/Net/SecureStreamSocket.h>
29#include <Poco/StreamCopier.h>
37using namespace Kernel;
45 "List of fileids to download from the data server");
47 "List of filenames to download from the data server");
48 declareProperty(
"DownloadPath",
"",
"The path to save the downloaded files.");
49 declareProperty(
"Session",
"",
"The session information of the catalog to use.");
52 "A list of file locations to the catalog datafiles.");
58 auto catalogInfoService = std::dynamic_pointer_cast<API::ICatalogInfoService>(
61 if (!catalogInfoService)
62 throw std::runtime_error(
"The catalog that you are using does not support "
63 "external downloading.");
68 std::vector<int64_t> fileIDs =
getProperty(
"FileIds");
69 std::vector<std::string> fileNames =
getProperty(
"FileNames");
74 std::vector<std::string> fileLocations;
78 std::vector<int64_t>::const_iterator fileID = fileIDs.begin();
79 std::vector<std::string>::const_iterator fileName = fileNames.begin();
82 for (; fileID != fileIDs.end(); ++fileID, ++fileName) {
84 double prog =
m_prog / (double(fileIDs.size()) / 10);
86 progress(prog,
"getting location string...");
89 std::string fileLocation = catalogInfoService->getFileLocation(*fileID);
91 g_log.
debug() <<
"CatalogDownloadDataFiles -> File location before transform is: " << fileLocation
92 <<
" mac path is : " << catalogInfo.
macPrefix() <<
'\n';
95 g_log.
debug() <<
"CatalogDownloadDataFiles -> File location after transform is: " << fileLocation <<
'\n';
98 std::ifstream hasAccessToArchives(fileLocation.c_str());
99 if (hasAccessToArchives) {
100 g_log.
information() <<
"File (" << *fileName <<
") located in archives (" << fileLocation <<
").\n";
101 fileLocations.emplace_back(fileLocation);
104 <<
") from archive. Beginning to download over Internet.\n";
105 progress(prog / 2,
"getting the url ....");
107 const std::string url = catalogInfoService->getDownloadURL(*fileID);
108 progress(prog,
"downloading over internet...");
110 fileLocations.emplace_back(fullPathDownloadedFile);
124 std::string extension = Poco::Path(fileName).getExtension();
125 std::transform(extension.begin(), extension.end(), extension.begin(), tolower);
126 return (extension ==
"raw" || extension ==
"nxs");
137 const std::string &fileName) {
138 std::string pathToDownloadedDatafile;
143 std::string path(uri.getPathAndQuery());
144 clock_t start = clock();
146 Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> certificateHandler =
147 new Poco::Net::AcceptCertificateHandler(
true);
150 const Poco::Net::Context::Ptr context =
151 new Poco::Net::Context(Poco::Net::Context::CLIENT_USE,
"",
"",
"", Poco::Net::Context::VERIFY_NONE);
154 Poco::Net::SSLManager::instance().initializeClient(
nullptr, certificateHandler, context);
157 Poco::Net::SecureStreamSocket socket{context};
158 Poco::Net::HTTPSClientSession session{socket};
159 session.setHost(uri.getHost());
160 session.setPort(uri.getPort());
162 Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
163 session.sendRequest(request);
166 Poco::Net::HTTPResponse response;
168 std::istream &responseStream = session.receiveResponse(response);
171 Poco::Net::HTTPResponse::HTTPStatus HTTPStatus = response.getStatus();
175 if (!IDSError.empty()) {
186 pathToDownloadedDatafile =
saveFiletoDisk(responseStream, fileName);
188 clock_t end = clock();
189 float diff = float(end - start) / CLOCKS_PER_SEC;
190 g_log.
information() <<
"Time taken to download file " << fileName <<
" is " << std::fixed << std::setprecision(2)
191 << diff <<
" seconds\n";
193 }
catch (Poco::Net::SSLException &
error) {
194 throw std::runtime_error(
error.displayText());
203 catch (Poco::Exception &
error) {
204 throw std::runtime_error(
error.displayText());
207 return pathToDownloadedDatafile;
218 std::string filepath = Poco::Path(
getPropertyValue(
"DownloadPath"), fileName).toString();
219 std::ios_base::openmode mode =
isDataFile(fileName) ? std::ios_base::binary : std::ios_base::out;
221 std::ofstream ofs(filepath.c_str(), mode);
222 if (ofs.rdstate() & std::ios::failbit)
225 Poco::StreamCopier::copyStream(rs, ofs);
#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.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
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.