Mantid
Loading...
Searching...
No Matches
ICat4Catalog.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
10#include "MantidAPI/Progress.h"
15#include "MantidKernel/Logger.h"
17
18namespace Mantid::ICat {
19using namespace Kernel;
20using namespace ICat4;
21using Types::Core::DateAndTime;
22
23namespace {
25Logger g_log("ICat4Catalog");
26} // namespace
27
28DECLARE_CATALOG(ICat4Catalog)
29
30ICat4Catalog::ICat4Catalog() : m_session() {}
31
39API::CatalogSession_sptr ICat4Catalog::login(const std::string &username, const std::string &password,
40 const std::string &endpoint, const std::string &facility) {
41 // Created the session object here in order to set the endpoint, which is used
42 // in setICATProxySettings.
43 // We can then manually set the sessionID later if it exists.
44 m_session = std::make_shared<API::CatalogSession>("", facility, endpoint);
45
46 // Securely set, including soap-endpoint.
49
50 // Used to authenticate the user.
52 ns1__loginResponse loginResponse;
53
54 // Used to add entries to the login class.
56
57 // Name of the authentication plugin in use.
58 std::string plugin;
59
60 if (endpoint.find("sns") != std::string::npos) {
61 plugin = std::string("ldap");
62 } else {
63 plugin = std::string("uows");
64 }
65 login.plugin = &plugin;
66
67 // Making string as cannot convert from const.
68 std::string userName(username);
69 std::string passWord(password);
70
71 std::string usernameKey("username");
72 std::string passwordKey("password");
73
74 // Instantiate an instance of an entry to prevent null pointer.
75 // This then allows us to push entries as required below.
76 std::vector<_ns1__login_credentials_entry> entries;
77 login.credentials.entry = &entries;
78
79 // Setting the username and pass credentials to the login class.
80 entry.key = &usernameKey;
81 entry.value = &userName;
82 entries.emplace_back(entry);
83
84 entry.key = &passwordKey;
85 entry.value = &passWord;
86 entries.emplace_back(entry);
87
88 int result = icat.login(&login, &loginResponse);
89
90 if (result == 0) {
91 m_session->setSessionId(*(loginResponse.return_));
92 } else {
94 }
95 // Will not reach here if user cannot log in (e.g. no session is created).
96 return m_session;
97}
98
105
106 ns1__logout request;
107 ns1__logoutResponse response;
108
109 std::string sessionID = m_session->getSessionId();
110 request.sessionId = &sessionID;
111
112 int result = icat.logout(&request, &response);
113
114 if (result == 0) {
115 m_session->setSessionId("");
116 } else {
117 throwErrorMessage(icat);
118 }
119}
120
127 // Contain the related where and join clauses for the search query based on
128 // user-input.
129 std::vector<std::string> whereClause, joinClause;
130
131 // Format the timestamps in order to compare them.
132 std::string startDate = formatDateTime(inputs.getStartDate(), "%Y-%m-%d %H:%M:%S");
133 std::string endDate = formatDateTime(inputs.getEndDate() + ((23 * 60 * 60) + (59 * 60) + 59), "%Y-%m-%d %H:%M:%S");
134
135 // Investigation startDate if endDate is not selected
136 if (inputs.getStartDate() != 0 && inputs.getEndDate() == 0) {
137 whereClause.emplace_back("inves.startDate >= '" + startDate + "'");
138 }
139
140 // Investigation endDate if startdate is not selected
141 if (inputs.getEndDate() != 0 && inputs.getStartDate() == 0) {
142 whereClause.emplace_back("inves.endDate <= '" + endDate + "'");
143 }
144
145 // Investigation Start and end date if both selected
146 if (inputs.getStartDate() != 0 && inputs.getEndDate() != 0) {
147 whereClause.emplace_back("inves.startDate BETWEEN '" + startDate + "' AND '" + endDate + "'");
148 }
149
150 // Investigation name (title)
151 if (!inputs.getInvestigationName().empty()) {
152 whereClause.emplace_back("inves.title LIKE '%" + inputs.getInvestigationName() + "%'");
153 }
154
155 // Investigation id
156 if (!inputs.getInvestigationId().empty()) {
157 whereClause.emplace_back("inves.name = '" + inputs.getInvestigationId() + "'");
158 }
159
160 // Investigation type
161 if (!inputs.getInvestigationType().empty()) {
162 joinClause.emplace_back("JOIN inves.type itype");
163 whereClause.emplace_back("itype.name = '" + inputs.getInvestigationType() + "'");
164 }
165
166 // Instrument name
167 if (!inputs.getInstrument().empty()) {
168 joinClause.emplace_back("JOIN inves.investigationInstruments invInst");
169 joinClause.emplace_back("JOIN invInst.instrument inst");
170 whereClause.emplace_back("inst.fullName = '" + inputs.getInstrument() + "'");
171 }
172
173 // Keywords
174 if (!inputs.getKeywords().empty()) {
175 joinClause.emplace_back("JOIN inves.keywords keywords");
176 whereClause.emplace_back("keywords.name IN ('" + inputs.getKeywords() + "')");
177 }
178
179 // Sample name
180 if (!inputs.getSampleName().empty()) {
181 joinClause.emplace_back("JOIN inves.samples sample");
182 whereClause.emplace_back("sample.name LIKE '%" + inputs.getSampleName() + "%'");
183 }
184
185 // If the user has selected the "My data only" button.
186 // (E.g. they want to display or search through all the data they have access
187 // to.
188 if (inputs.getMyData()) {
189 joinClause.emplace_back("JOIN inves.investigationUsers users");
190 joinClause.emplace_back("JOIN users.user user");
191 whereClause.emplace_back("user.name = :user");
192 }
193
194 // Investigators complete name.
195 if (!inputs.getInvestigatorSurName().empty()) {
196 // We join another investigationUsers & user tables as we need two aliases.
197 joinClause.emplace_back("JOIN inves.investigationUsers usrs");
198 joinClause.emplace_back("JOIN usrs.user usr");
199 whereClause.emplace_back("usr.fullName LIKE '%" + inputs.getInvestigatorSurName() + "%'");
200 }
201
202 // Similar to above. We check if either has been input,
203 // join the related table and add the specific WHERE clause.
204 if (!inputs.getDatafileName().empty() || (inputs.getRunStart() > 0 && inputs.getRunEnd() > 0)) {
205 joinClause.emplace_back("JOIN inves.datasets dataset");
206 joinClause.emplace_back("JOIN dataset.datafiles datafile");
207
208 if (!inputs.getDatafileName().empty()) {
209 whereClause.emplace_back("datafile.name LIKE '%" + inputs.getDatafileName() + "%'");
210 }
211
212 if (inputs.getRunStart() > 0 && inputs.getRunEnd() > 0) {
213 joinClause.emplace_back("JOIN datafile.parameters datafileparameters");
214 joinClause.emplace_back("JOIN datafileparameters.type dtype");
215 whereClause.emplace_back("dtype.name='run_number' AND "
216 "datafileparameters.numericValue BETWEEN " +
217 Strings::toString(inputs.getRunStart()) + " AND " +
218 Strings::toString(inputs.getRunEnd()) + "");
219 }
220 }
221
222 std::string query;
223
224 // This prevents the user searching the entire archive (E.g. there is no
225 // "default" query).
226 if (!whereClause.empty() || !joinClause.empty()) {
227 std::string from, join, where, orderBy, includes;
228
229 from = " FROM Investigation inves ";
230 join = Strings::join(joinClause.begin(), joinClause.end(), " ");
231 where = Strings::join(whereClause.begin(), whereClause.end(), " AND ");
232 orderBy = " ORDER BY inves.id DESC";
233 includes = " INCLUDE inves.facility, "
234 "inves.investigationInstruments.instrument, inves.parameters";
235
236 // As we joined all WHERE clause with AND we need to include the WHERE at
237 // the start of the where segment.
238 where.insert(0, " WHERE ");
239 // Build the query from the result.
240 query = from + join + where + orderBy + includes;
241 }
242
243 return (query);
244}
245
255 const int &offset, const int &limit) {
256 std::string query = buildSearchQuery(inputs);
257
258 // Check if the query built was valid.
259 if (query.empty())
260 throw std::runtime_error("You have not input any terms to search for.");
261
262 // Modify the query to include correct SELECT and LIMIT clauses.
263 query.insert(0, "SELECT DISTINCT inves");
264 query.append(" LIMIT " + std::to_string(offset) + "," + std::to_string(limit));
265
268
269 auto searchResults = performSearch(icat, query);
270 saveInvestigations(searchResults, outputws);
271}
272
280
281 std::string query = buildSearchQuery(inputs);
282 if (query.empty())
283 throw std::runtime_error("You have not input any terms to search for.");
284 query.insert(0, "SELECT COUNT(DISTINCT inves)");
285
286 auto searchResults = performSearch(icat, query);
287 auto numRes = dynamic_cast<xsd__long *>(searchResults.at(0));
288
289 if (numRes) {
290 g_log.debug() << "The number of paging results returned in "
291 "ICat4Catalog::getNumberOfSearchResults is: "
292 << numRes->__item << "\n";
293 return numRes->__item;
294 } else
295 return -1;
296}
297
305
306 std::string query = "SELECT DISTINCT inves "
307 "FROM Investigation inves "
308 "JOIN inves.investigationUsers users "
309 "JOIN users.user user "
310 "WHERE user.name = :user "
311 "ORDER BY inves.id DESC "
312 "INCLUDE inves.facility, inves.investigationInstruments.instrument, "
313 "inves.parameters";
314
315 auto searchResults = performSearch(icat, query);
316 saveInvestigations(searchResults, outputws);
317}
318
324void ICat4Catalog::saveInvestigations(std::vector<xsd__anyType *> response, API::ITableWorkspace_sptr &outputws) {
325 if (outputws->getColumnNames().empty()) {
326 // Add rows headers to the output workspace.
327 outputws->addColumn("long64", "DatabaseID");
328 outputws->addColumn("str", "InvestigationID");
329 outputws->addColumn("str", "Facility");
330 outputws->addColumn("str", "Title");
331 outputws->addColumn("str", "Instrument");
332 outputws->addColumn("str", "Run range");
333 outputws->addColumn("str", "Start date");
334 outputws->addColumn("str", "End date");
335 outputws->addColumn("str", "SessionID");
336 }
337
338 // Add data to each row in the output workspace.
339 std::vector<xsd__anyType *>::const_iterator iter;
340 for (iter = response.begin(); iter != response.end(); ++iter) {
341 // Cast from xsd__anyType to subclass (xsd__string).
342 auto *investigation = dynamic_cast<ns1__investigation *>(*iter);
343 if (investigation) {
344 API::TableRow table = outputws->appendRow();
345 // Used to insert an empty string into the cell if value does not exist.
346 std::string emptyCell;
347
348 // Now add the relevant investigation data to the table (They always
349 // exist).
350 savetoTableWorkspace(investigation->id, table);
351 savetoTableWorkspace(investigation->name, table);
352 savetoTableWorkspace(investigation->facility->name, table);
353 savetoTableWorkspace(investigation->title, table);
354 savetoTableWorkspace(investigation->investigationInstruments.at(0)->instrument->name, table);
355
356 // Verify that the run parameters vector exist prior to doing anything.
357 // Since some investigations may not have run parameters.
358 if (!investigation->parameters.empty()) {
359 savetoTableWorkspace(investigation->parameters[0]->stringValue, table);
360 } else {
361 savetoTableWorkspace(&emptyCell, table);
362 }
363
364 // Again, we need to check first if start and end date exist prior to
365 // insertion.
366 if (investigation->startDate) {
367 std::string startDate = formatDateTime(*investigation->startDate, "%Y-%m-%d");
368 savetoTableWorkspace(&startDate, table);
369 } else {
370 savetoTableWorkspace(&emptyCell, table);
371 }
372
373 if (investigation->endDate) {
374 std::string endDate = formatDateTime(*investigation->endDate, "%Y-%m-%d");
375 savetoTableWorkspace(&endDate, table);
376 } else {
377 savetoTableWorkspace(&emptyCell, table);
378 }
379 std::string sessionID = m_session->getSessionId();
380 savetoTableWorkspace(&sessionID, table);
381 } else {
382 throw std::runtime_error("ICat4Catalog::saveInvestigations expected an "
383 "investigation. Please contact the Mantid "
384 "development team.");
385 }
386 }
387}
388
394void ICat4Catalog::getDataSets(const std::string &investigationId, Mantid::API::ITableWorkspace_sptr &outputws) {
397
398 auto searchResults = performSearch(icat, "Dataset INCLUDE DatasetType, Datafile, "
399 "Investigation <-> Investigation[name = '" +
400 investigationId + "']");
401 saveDataSets(searchResults, outputws);
402}
403
410void ICat4Catalog::saveDataSets(const std::vector<xsd__anyType *> &response, API::ITableWorkspace_sptr &outputws) {
411 if (outputws->getColumnNames().empty()) {
412 // Add rows headers to the output workspace.
413 outputws->addColumn("long64", "ID");
414 outputws->addColumn("str", "Name");
415 outputws->addColumn("str", "Description");
416 outputws->addColumn("str", "Type");
417 outputws->addColumn("str", "Related investigation ID");
418 outputws->addColumn("size_t", "Number of datafiles");
419 }
420
421 std::string emptyCell;
422 for (auto &iter : response) {
423 auto *dataset = dynamic_cast<ns1__dataset *>(iter);
424 if (dataset) {
425 API::TableRow table = outputws->appendRow();
426
427 savetoTableWorkspace(dataset->id, table);
428 savetoTableWorkspace(dataset->name, table);
429
430 if (dataset->description)
431 savetoTableWorkspace(dataset->description, table);
432 else
433 savetoTableWorkspace(&emptyCell, table);
434
435 if (dataset->type)
436 savetoTableWorkspace(dataset->type->name, table);
437 else
438 savetoTableWorkspace(&emptyCell, table);
439
440 if (dataset->investigation)
441 savetoTableWorkspace(dataset->investigation->name, table);
442 else
443 savetoTableWorkspace(&emptyCell, table);
444
445 size_t datafileCount = dataset->datafiles.size();
446 savetoTableWorkspace(&datafileCount, table);
447 } else {
448 throw std::runtime_error("ICat4Catalog::saveDataSets expected a dataset. "
449 "Please contact the Mantid development team.");
450 }
451 }
452}
453
459void ICat4Catalog::getDataFiles(const std::string &investigationId, Mantid::API::ITableWorkspace_sptr &outputws) {
462
463 auto searchResults = performSearch(icat, "Datafile <-> Dataset <-> Investigation[name = '" + investigationId + "']");
464 saveDataFiles(searchResults, outputws);
465}
466
472void ICat4Catalog::saveDataFiles(std::vector<xsd__anyType *> response, API::ITableWorkspace_sptr &outputws) {
473 if (outputws->getColumnNames().empty()) {
474 // Add rows headers to the output workspace.
475 outputws->addColumn("str", "Name");
476 outputws->addColumn("str", "Location");
477 outputws->addColumn("str", "Create Time");
478 outputws->addColumn("long64", "Id");
479 outputws->addColumn("long64", "File size(bytes)");
480 outputws->addColumn("str", "File size");
481 outputws->addColumn("str", "Description");
482 }
483
484 std::vector<xsd__anyType *>::const_iterator iter;
485 for (iter = response.begin(); iter != response.end(); ++iter) {
486 auto *datafile = dynamic_cast<ns1__datafile *>(*iter);
487 if (datafile) {
488 API::TableRow table = outputws->appendRow();
489 // Now add the relevant investigation data to the table.
490 savetoTableWorkspace(datafile->name, table);
491 savetoTableWorkspace(datafile->location, table);
492
493 std::string createDate = formatDateTime(*datafile->createTime, "%Y-%m-%d %H:%M:%S");
494 savetoTableWorkspace(&createDate, table);
495
496 savetoTableWorkspace(datafile->id, table);
497 savetoTableWorkspace(datafile->fileSize, table);
498
499 std::string fileSize = bytesToString(*datafile->fileSize);
500 savetoTableWorkspace(&fileSize, table);
501
502 if (datafile->description)
503 savetoTableWorkspace(datafile->description, table);
504 } else {
505 throw std::runtime_error("ICat4Catalog::saveDataFiles expected a "
506 "datafile. Please contact the Mantid "
507 "development team.");
508 }
509 }
510}
511
516void ICat4Catalog::listInstruments(std::vector<std::string> &instruments) {
519
520 auto searchResults = performSearch(icat, "Instrument.fullName ORDER BY fullName");
521
522 for (auto &searchResult : searchResults) {
523 auto instrument = dynamic_cast<xsd__string *>(searchResult);
524 if (instrument)
525 instruments.emplace_back(instrument->__item);
526 }
527}
528
533void ICat4Catalog::listInvestigationTypes(std::vector<std::string> &invstTypes) {
536
537 auto searchResults = performSearch(icat, "InvestigationType.name ORDER BY name");
538
539 for (auto &searchResult : searchResults) {
540 auto investigationType = dynamic_cast<xsd__string *>(searchResult);
541 if (investigationType)
542 invstTypes.emplace_back(investigationType->__item);
543 }
544}
545
551const std::string ICat4Catalog::getFileLocation(const long long &fileID) {
554
555 auto searchResults = performSearch(icat, "Datafile[id = '" + std::to_string(fileID) + "']");
556 auto datafile = dynamic_cast<ns1__datafile *>(searchResults.at(0));
557
558 if (datafile && datafile->location)
559 return *(datafile->location);
560 else
561 return "";
562}
563
569const std::string ICat4Catalog::getDownloadURL(const long long &fileID) {
570 // Obtain the URL from the Facilities.xml file.
571 std::string url = ConfigService::Instance().getFacility(m_session->getFacility()).catalogInfo().externalDownloadURL();
572
573 // Set the REST features of the URL.
574 std::string session = "sessionId=" + m_session->getSessionId();
575 std::string datafile = "&datafileIds=" + std::to_string(fileID);
576 std::string outname = "&outname=" + std::to_string(fileID);
577
578 // Add all the REST pieces to the URL.
579 url += ("getData?" + session + datafile + outname + "&zip=false");
580 g_log.debug() << "The download URL in ICat4Catalog::getDownloadURL is: " << url << '\n';
581 return url;
582}
583
592const std::string ICat4Catalog::getUploadURL(const std::string &investigationID, const std::string &createFileName,
593 const std::string &dataFileDescription) {
594 // Obtain the URL from the Facilities.xml file.
595 std::string url = ConfigService::Instance().getFacility(m_session->getFacility()).catalogInfo().externalDownloadURL();
596
597 // Set the elements of the URL.
598 std::string session = "sessionId=" + m_session->getSessionId();
599 std::string name = "&name=" + createFileName;
600 std::string datasetId = "&datasetId=" + std::to_string(getMantidDatasetId(investigationID));
601 std::string description = "&description=" + dataFileDescription;
602
603 // Add pieces of URL together.
604 url += ("put?" + session + name + datasetId + description + "&datafileFormatId=1");
605 g_log.debug() << "The upload URL in ICat4Catalog::getUploadURL is: " << url << '\n';
606 return url;
607}
608
618
619 auto ws = API::WorkspaceFactory::Instance().createTable("TableWorkspace");
620 // Populate the workspace with all the investigations that
621 // the user is an investigator off and has READ access to.
622 myData(ws);
623
624 // Remove each investigation returned from `myData`
625 // were the user does not have create/write access.
626 for (int row = static_cast<int>(ws->rowCount()) - 1; row >= 0; --row) {
627 ns1__dataset dataset;
628 ns1__datafile datafile;
629
630 // Verify if the user can CREATE datafiles in the "mantid" specific dataset.
631 int64_t datasetID = getMantidDatasetId(ws->getRef<std::string>("InvestigationID", row));
632 std::string datafileName = "tempName.nxs";
633
634 dataset.id = &datasetID;
635 datafile.name = &datafileName;
636 datafile.dataset = &dataset;
637
639 ws->removeRow(row);
640 }
641
642 return ws;
643}
644
651
652 ns1__refresh request;
653 ns1__refreshResponse response;
654
655 std::string sessionID = m_session->getSessionId();
656 request.sessionId = &sessionID;
657
658 int result = icat.refresh(&request, &response);
659 // An error occurred!
660 if (result != 0)
661 throwErrorMessage(icat);
662}
663
669 if (soap_ssl_client_context(&icat, SOAP_SSL_CLIENT, /* use SOAP_SSL_DEFAULT in production code */
670 nullptr, /* keyfile: required only when client must authenticate to
671 server (see SSL docs on how to obtain this file) */
672 nullptr, /* password to read the keyfile */
673 nullptr, /* optional cacert file to store trusted certificates */
674 nullptr, /* optional capath to directory with trusted certificates */
675 nullptr /* if randfile!=NULL: use a file with random data to seed
676 randomness */
677 )) {
678 throwErrorMessage(icat);
679 }
680}
681
687 char buf[600];
688 const int len = 600;
689 icat.soap_sprint_fault(buf, len);
690 std::string error(buf);
691 std::string begmsg("<message>");
692 std::string endmsg("</message>");
693
694 std::basic_string<char>::size_type start = error.find(begmsg);
695 std::basic_string<char>::size_type end = error.find(endmsg);
696 std::string exception;
697
698 if (start != std::string::npos && end != std::string::npos) {
699 exception = error.substr(start + begmsg.length(), end - (start + begmsg.length()));
700 }
701 // If no error is returned by ICAT then there is a connection problem.
702 if (exception.empty())
703 exception = "ICAT appears to be offline. Please check your connection or "
704 "report this issue.";
705
706 throw std::runtime_error(exception);
707}
708
713std::string ICat4Catalog::bytesToString(int64_t &fileSize) {
714 const char *args[] = {"B", "KB", "MB", "GB"};
715 std::vector<std::string> units(args, args + 4);
716
717 unsigned order = 0;
718
719 while (fileSize >= 1024 && order + 1 < units.size()) {
720 order++;
721 fileSize = fileSize / 1024;
722 }
723
724 return std::to_string(fileSize) + units.at(order);
725}
726
733std::string ICat4Catalog::formatDateTime(const time_t &timestamp, const std::string &format) {
734 auto dateTime = DateAndTime(boost::posix_time::from_time_t(timestamp));
735 return (dateTime.toFormattedString(format));
736}
737
745int64_t ICat4Catalog::getMantidDatasetId(const std::string &investigationID) {
748
749 auto searchResults = performSearch(icat, "Dataset <-> Investigation[name = '" + investigationID + "']");
750
751 int64_t datasetID = -1;
752 for (auto &searchResult : searchResults) {
753 auto dataset = dynamic_cast<ns1__dataset *>(searchResult);
754 if (dataset && *(dataset->name) == "mantid")
755 datasetID = *(dataset->id);
756 }
757
758 if (datasetID == -1)
759 datasetID = createMantidDataset(investigationID);
760 g_log.debug() << "The dataset ID of the mantid dataset was: " << datasetID << "\n";
761
762 return datasetID;
763}
764
771int64_t ICat4Catalog::createMantidDataset(const std::string &investigationID) {
774
775 // We need to obtain an already existing datasetType as it's not recommended
776 // to create a new one.
777 auto datasetTypeSearch = performSearch(icat, "DatasetType[name ='analyzed']");
778 auto datasetType = dynamic_cast<ns1__datasetType *>(datasetTypeSearch.at(0));
779
780 auto investigationSearch = performSearch(icat, "Investigation[name = '" + investigationID + "']");
781 auto investigation = dynamic_cast<ns1__investigation *>(investigationSearch.at(0));
782
783 ns1__dataset dataset;
784 std::string datasetName = "mantidTempNotDuplicate";
785
786 dataset.name = &datasetName;
787 dataset.complete = false;
788 dataset.type = datasetType;
789 dataset.investigation = investigation;
790
791 int64_t datasetID = -1;
792
794 ns1__create createRequest;
795 ns1__createResponse createResponse;
796
797 // We have to re-set the dataset name as when performing isAccessAllowed
798 // an error will be thrown if the dataset already exists.
799 std::string mantidName = "mantid";
800 dataset.name = &mantidName;
801
802 std::string sessionID = m_session->getSessionId();
803 createRequest.sessionId = &sessionID;
804 createRequest.bean = &dataset;
805
806 if (icat.create(&createRequest, &createResponse) == SOAP_OK) {
807 g_log.debug() << "Creating a new dataset named: " << *(dataset.name) << " with investigationID "
808 << investigationID << "\n";
809 datasetID = createResponse.return_;
810 }
811 // Do not throw error from ICAT as we want to continue on GUI. Instead,
812 // return -1 below.
813 }
814
815 g_log.debug() << "The dataset ID returned from ICat4Catalog::createMantidDataset was: " << datasetID << "\n";
816 return datasetID; // Since we did not have access or could not create the file
817 // the default value (-1).
818}
819
824 // The soapEndPoint is only set when the user logs into the catalog.
825 // If it's not set the correct error is returned (invalid sessionID) from the
826 // ICAT server.
827 if (m_session->getSoapEndpoint().empty())
828 return;
829 // Stop receiving packets from ICAT server after period of time.
830 icat.recv_timeout = boost::lexical_cast<int>(ConfigService::Instance().getString("catalog.timeout.value"));
831 // Set the soap-endpoint of the catalog we want to use.
832 icat.soap_endpoint = m_session->getSoapEndpoint().c_str();
833 // Sets SSL authentication scheme
834 setSSLContext(icat);
835}
836
843std::vector<xsd__anyType *> ICat4Catalog::performSearch(ICATPortBindingProxy &icat, std::string query) {
844 ns1__search request;
845 ns1__searchResponse response;
846
847 std::string sessionID = m_session->getSessionId();
848 request.sessionId = &sessionID;
849 request.query = &query;
850
851 g_log.debug() << "The search query sent to ICAT was: \n" << query << '\n';
852
853 std::vector<xsd__anyType *> searchResults;
854
855 if (icat.search(&request, &response) == SOAP_OK) {
856 searchResults = response.return_;
857 } else {
858 throwErrorMessage(icat);
859 }
860
861 return searchResults;
862}
863
871template <class T> bool ICat4Catalog::isAccessAllowed(ns1__accessType accessType, T &bean) {
874
875 ns1__isAccessAllowed request;
877
878 std::string sessionID = m_session->getSessionId();
879 request.sessionId = &sessionID;
880
881 ns1__accessType_ type;
882 type.__item = accessType;
883
884 request.accessType = &type.__item;
885 request.bean = &bean;
886
887 if (icat.isAccessAllowed(&request, &response) == SOAP_OK)
888 return response.return_;
889 else
890 throwErrorMessage(icat);
891 return false;
892}
893} // namespace Mantid::ICat
#define DECLARE_CATALOG(classname)
double error
Definition: IndexPeaks.cpp:133
virtual int isAccessAllowed(ns1__isAccessAllowed *ns1__isAccessAllowed_, ns1__isAccessAllowedResponse *ns1__isAccessAllowedResponse_)
Web service operation 'isAccessAllowed' (returns error code or SOAP_OK)
virtual int refresh(ns1__refresh *ns1__refresh_, ns1__refreshResponse *ns1__refreshResponse_)
Web service operation 'refresh' (returns error code or SOAP_OK)
virtual char * soap_sprint_fault(char *buf, size_t len)
Put fault into buffer.
const char * soap_endpoint
Endpoint URL of service 'ICATPortBindingProxy' (change as needed)
virtual int logout(ns1__logout *ns1__logout_, ns1__logoutResponse *ns1__logoutResponse_)
Web service operation 'logout' (returns error code or SOAP_OK)
virtual int create(ns1__create *ns1__create_, ns1__createResponse *ns1__createResponse_)
Web service operation 'create' (returns error code or SOAP_OK)
virtual int search(ns1__search *ns1__search_, ns1__searchResponse *ns1__searchResponse_)
Web service operation 'search' (returns error code or SOAP_OK)
virtual int login(ns1__login *ns1__login_, ns1__loginResponse *ns1__loginResponse_)
Web service operation 'login' (returns error code or SOAP_OK)
Definition: ICat4Stub.h:922
std::string * value
Definition: ICat4Stub.h:925
std::string * key
Definition: ICat4Stub.h:924
enum ns1__accessType __item
Definition: ICat4Stub.h:318
ns1__entityBaseBean * bean
Definition: ICat4Stub.h:456
std::string * sessionId
Definition: ICat4Stub.h:455
ns1__dataset * dataset
Definition: ICat4Stub.h:1453
std::string * name
Definition: ICat4Stub.h:1459
ns1__datasetType * type
Definition: ICat4Stub.h:1554
std::string * name
Definition: ICat4Stub.h:1550
ns1__investigation * investigation
Definition: ICat4Stub.h:1548
enum ns1__accessType * accessType
Definition: ICat4Stub.h:1289
ns1__entityBaseBean * bean
Definition: ICat4Stub.h:1288
std::string * return_
Definition: ICat4Stub.h:982
std::string * sessionId
Definition: ICat4Stub.h:1372
std::string * sessionId
Definition: ICat4Stub.h:890
std::vector< xsd__anyType * > return_
Definition: ICat4Stub.h:1349
std::string * sessionId
Definition: ICat4Stub.h:1330
std::string * query
Definition: ICat4Stub.h:1331
TableRow represents a row in a TableWorkspace.
Definition: TableRow.h:39
This class is used in Catalog Search service to set/get all the inputs to search for.
const std::string & getInvestigationName() const
Get the name of the investigation to search for.
const double & getRunStart() const
Get the start run from user input.
const std::string & getSampleName() const
Get the sample name.
const std::string & getInvestigatorSurName() const
Get the investigators name.
const std::string & getInvestigationId() const
Get the investigation id.
const time_t & getStartDate() const
Get the investigation start date.
const time_t & getEndDate() const
Get the investigation end date.
const std::string & getDatafileName() const
Get the datafile name.
const std::string & getInstrument() const
Get the instrument name.
const std::string & getKeywords() const
Get the keywords to search investigations for.
const std::string & getInvestigationType() const
Get the investigation type.
const double & getRunEnd() const
Get the end run.
bool getMyData() const
Get the "my data only" flag.
This class is responsible for the implementation of ICat4 version based information catalogs.
Definition: ICat4Catalog.h:23
const std::string getFileLocation(const long long &fileID) override
Get the file location string(s) from archive.
std::string buildSearchQuery(const CatalogSearchParam &inputs)
Creates a search query string based on inputs provided by the user.
void listInvestigationTypes(std::vector< std::string > &invstTypes) override
Get investigationtypes list.
std::vector< ICat4::xsd__anyType * > performSearch(ICat4::ICATPortBindingProxy &icat, std::string query)
Returns the results of a search against ICAT for a given query.
int64_t getNumberOfSearchResults(const CatalogSearchParam &inputs) override
Obtain the number of results returned by the search method.
void saveInvestigations(std::vector< ICat4::xsd__anyType * > response, API::ITableWorkspace_sptr &outputws)
Saves investigations to a table workspace.
void setSSLContext(ICat4::ICATPortBindingProxy &icat)
Defines the SSL authentication scheme.
bool isAccessAllowed(ICat4::ns1__accessType accessType, T &bean)
Is the specified access type allowed for a specific bean?
void keepAlive() override
Keep current session alive.
void getDataFiles(const std::string &investigationId, Mantid::API::ITableWorkspace_sptr &outputws) override
Get datafiles.
void logout() override
Log the user out of the catalog system.
void savetoTableWorkspace(T *input, Mantid::API::TableRow &table)
Template method to save data to table workspace.
Definition: ICat4Catalog.h:98
void saveDataFiles(std::vector< ICat4::xsd__anyType * > response, API::ITableWorkspace_sptr &outputws)
Saves result from "getDataFiles" to workspace.
void saveDataSets(const std::vector< ICat4::xsd__anyType * > &response, API::ITableWorkspace_sptr &outputws)
Loops through the response vector and saves the datasets details to a table workspace.
std::string bytesToString(int64_t &fileSize)
Convert a file size to human readable file format.
API::CatalogSession_sptr m_session
Definition: ICat4Catalog.h:91
void myData(Mantid::API::ITableWorkspace_sptr &outputws) override
Show the logged in user's investigations search results.
int64_t createMantidDataset(const std::string &investigationID)
Creates a dataset for an investigation (based on ID) named 'mantid' if it does not already exist.
std::string formatDateTime(const time_t &timestamp, const std::string &format)
Formats a given timestamp to human readable datetime.
void listInstruments(std::vector< std::string > &instruments) override
Get instruments list.
void setICATProxySettings(ICat4::ICATPortBindingProxy &icat)
Sets the soap-endpoint & SSL context for the given ICAT proxy.
void search(const CatalogSearchParam &inputs, Mantid::API::ITableWorkspace_sptr &outputws, const int &offset, const int &limit) override
Search the catalog for data.
const std::string getDownloadURL(const long long &fileID) override
Get the url(s) based on the fileID.
void getDataSets(const std::string &investigationId, Mantid::API::ITableWorkspace_sptr &outputws) override
Get datasets.
API::ITableWorkspace_sptr getPublishInvestigations() override
Obtains the investigations that the user can publish to and saves related information to a workspace.
API::CatalogSession_sptr login(const std::string &username, const std::string &password, const std::string &endpoint, const std::string &facility) override
Log the user into the catalog system.
const std::string getUploadURL(const std::string &investigationID, const std::string &createFileName, const std::string &dataFileDescription) override
get URL of where to PUT (publish) files.
void throwErrorMessage(ICat4::ICATPortBindingProxy &icat)
Throws an error message (returned by gsoap) to Mantid upper layer.
int64_t getMantidDatasetId(const std::string &investigationID)
Search the archive & obtain the "mantid" dataset ID for a specific investigation if it exists.
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Definition: ICat4H.h:14
ns1__accessType
Definition: ICat4Stub.h:75
@ ns1__accessType__CREATE
Definition: ICat4Stub.h:79
std::shared_ptr< CatalogSession > CatalogSession_sptr
std::shared_ptr< ITableWorkspace > ITableWorkspace_sptr
shared pointer to Mantid::API::ITableWorkspace
Kernel::Logger g_log("ExperimentInfo")
static logger object
DLLExport std::string join(ITERATOR_TYPE begin, ITERATOR_TYPE end, const std::string &separator, typename std::enable_if<!(std::is_same< typename std::iterator_traits< ITERATOR_TYPE >::iterator_category, std::random_access_iterator_tag >::value)>::type *=nullptr)
Join a set or vector of (something that turns into a string) together into one string,...
Definition: Strings.h:84
std::string toString(const T &value)
Convert a number to a string.
Definition: Strings.cpp:703
std::string to_string(const wide_integer< Bits, Signed > &n)