1 /**
  2  * @fileOverview
  3  * @author <a href="https://www.labkey.org">LabKey</a> (<a href="mailto:info@labkey.com">info@labkey.com</a>)
  4  * @license Copyright (c) 2012-2019 LabKey Corporation
  5  * <p/>
  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  * <p/>
 10  * http://www.apache.org/licenses/LICENSE-2.0
 11  * <p/>
 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  * <p/>
 18  */
 19 
 20 /**
 21  * @namespace Pipeline static class that allows programmatic manipulation of the data pipeline.
 22  */
 23 LABKEY.Pipeline = new function(){
 24     // private methods and data
 25 
 26     //public interface
 27     /** @scope LABKEY.Pipeline */
 28     return {
 29         /**
 30          * Gets the container in which the pipeline for this container is defined. This may be the
 31          * container in which the request was made, or a parent container if the pipeline was defined
 32          * there.
 33          * @param {Object} config A configuration object with the following properties.
 34          * @param {Function} config.success The function to call with the resulting information.
 35          * This function will be passed a single parameter of type object, which will have the following
 36          * properties:
 37          * <ul>
 38          *  <li>containerPath: the container path in which the pipeline is defined. If no pipeline has
 39          * been defined in this container hierarchy, the value of this property will be null.</li>
 40          *  <li>webDavURL: the WebDavURL for the pipeline root.</li>
 41          * </ul>
 42          * @param {Function} [config.failure] A function to call if an error occurs. This function
 43          * will receive one parameter of type object with the following properties:
 44          * <ul>
 45          *  <li>exception: The exception message.</li>
 46          * </ul>
 47          * @param {String} [config.containerPath] The container in which to make the request (defaults to current container)
 48          * @param {Object} [config.scope] The scope to use when calling the callbacks (defaults to this).
 49          */
 50         getPipelineContainer : function(config) {
 51             LABKEY.Ajax.request({
 52                 url: LABKEY.ActionURL.buildURL("pipeline", "getPipelineContainer.api", config.containerPath),
 53                 method: 'GET',
 54                 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope),
 55                 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true)
 56             });
 57         },
 58 
 59         /**
 60          * Gets the protocols that have been saved for a particular pipeline.
 61          * 
 62          * @param {Object} config A configuration object with the following properties.
 63          * @param {String} config.taskId Identifier for the pipeline.
 64          * @param {String} config.path relative path from the folder's pipeline root
 65          * @param {Boolean} config.includeWorkbooks If true, protocols from workbooks under the selected container will also be included
 66          * @param {String} [config.containerPath] The container in which to make the request (defaults to current container)
 67          * @param {Function} config.success The function to call with the resulting information.
 68          * This function will be passed a list of protocol objects, which will have the following properties:
 69          * <ul>
 70          *  <li>name: name of the saved protocol.</li>
 71          *  <li>description: description of the saved protocol, if provided.</li>
 72          *  <li>xmlParameters: bioml representation of the parameters defined by this protocol.</li>
 73          *  <li>jsonParameters: JSON representation of the parameters defined by this protocol.</li>
 74          *  <li>containerPath: The container path where this protocol was saved</li>
 75          * </ul>
 76          * @param {Function} [config.failure] A function to call if an error occurs. This function
 77          * will receive one parameter of type object with the following properties:
 78          * <ul>
 79          *  <li>exception: The exception message.</li>
 80          * </ul>
 81          * @param {Object} [config.scope] The scope to use when calling the callbacks (defaults to this).
 82          */
 83         getProtocols : function(config) {
 84             var params = {
 85                 taskId: config.taskId,
 86                 includeWorkbooks: !!config.includeWorkbooks,
 87                 path: config.path
 88             };
 89 
 90             var containerPath = config.containerPath ? config.containerPath : LABKEY.ActionURL.getContainer();
 91             var url = LABKEY.ActionURL.buildURL("pipeline-analysis", "getSavedProtocols.api", containerPath);
 92             var onSuccess = LABKEY.Utils.getOnSuccess(config);
 93             LABKEY.Ajax.request({
 94                 url: url,
 95                 method: 'POST',
 96                 params: params,
 97                 success: LABKEY.Utils.getCallbackWrapper(function(data, response){
 98                         onSuccess.call(this, data.protocols, data.defaultProtocolName, response);
 99                 }, config.scope),
100                 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true)
101             });
102         },
103 
104         /**
105          * Gets the status of analysis using a particular protocol for a particular pipeline.
106          *
107          * @param {Object} config A configuration object with the following properties.
108          * @param {String} config.taskId Identifier for the pipeline.
109          * @param {String} config.path relative path from the folder's pipeline root
110          * @param {String[]} config.files names of the file within the subdirectory described by the path property
111          * @param {String} config.protocolName name of the analysis protocol
112          * @param {String} [config.containerPath] The container in which to make the request (defaults to current container)
113          * @param {Function} config.success The function to call with the resulting information.
114          * This function will be passed two arguments, a list of file status objects (described below) and the
115          * name of the action that would be performed on the files if the user initiated processing
116          * ('Retry' or 'Analyze', for example).
117          * <ul>
118          *  <li>name: name of the file, a String.</li>
119          *  <li>status: status of the file, a String</li>
120          * </ul>
121          * @param {Function} [config.failure] A function to call if an error occurs. This function
122          * will receive one parameter of type object with the following properties:
123          * <ul>
124          *  <li>exception: The exception message.</li>
125          * </ul>
126          * @param {Object} [config.scope] The scope to use when calling the callbacks (defaults to this).
127          */
128         getFileStatus : function(config)
129         {
130             var params = {
131                 taskId: config.taskId,
132                 path: config.path,
133                 file: config.files,
134                 protocolName: config.protocolName
135             };
136 
137             var containerPath = config.containerPath ? config.containerPath : LABKEY.ActionURL.getContainer();
138             var url = LABKEY.ActionURL.buildURL("pipeline-analysis", "getFileStatus.api", containerPath);
139             var onSuccess = LABKEY.Utils.getOnSuccess(config);
140             LABKEY.Ajax.request({
141                 url: url,
142                 method: 'POST',
143                 timeout: 60000000,
144                 params: params,
145                 success: LABKEY.Utils.getCallbackWrapper(function(data, response){
146                         onSuccess.call(this, data.files, data.submitType, response);
147                 }, config.scope),
148                 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true)
149             });
150         },
151 
152         /**
153          * Starts analysis of a set of files using a particular protocol definition with a particular pipeline.
154          *
155          * @param {Object} config A configuration object with the following properties.
156          * @param {String} config.taskId Identifier for the pipeline.
157          * @param {String} config.path relative path from the folder's pipeline root
158          * @param {String[]} config.files names of the file within the subdirectory described by the path property
159          * @param {Integer[]} config.fileIds data IDs of files be to used as inputs for this pipeline.  these correspond to the rowIds from the table ext.data.  they do not need to be located within the file path provided.  the user does need read access to the container associated with each file.
160          * @param {String} config.protocolName name of the analysis protocol
161          * @param {String} [config.protocolDescription] description of the analysis protocol
162          * @param {String} [config.pipelineDescription] description displayed in the pipeline
163          * @param {String|Element} [config.xmlParameters] XML representation of the protocol description. Not allowed
164          * if a protocol with the same name has already been saved. If no protocol with the same name exists, either
165          * this property or jsonParameters must be specified.
166          * @param {String|Object} [config.jsonParameters] JSON representation of the protocol description. Not allowed
167          * if a protocol with the same name has already been saved. If no protocol with the same name exists, either
168          * this property or xmlParameters must be specified.
169          * @param {String} [config.saveProtocol] if no protocol with this name already exists, whether or not to save
170          * this protocol definition for future use. Defaults to true.
171          *
172          * @param {String} [config.containerPath] The container in which to make the request (defaults to current container)
173          * @param {Function} config.success A function to call if this operation is successful.
174          * @param {Function} [config.failure] A function to call if an error occurs. This function
175          * will receive one parameter of type object with the following properties:
176          * <ul>
177          *  <li>exception: The exception message.</li>
178          * </ul>
179          * @param {Object} [config.scope] The scope to use when calling the callbacks (defaults to this).
180          */
181         startAnalysis : function(config) {
182             if (!config.protocolName)
183             {
184                 throw "Invalid config, must include protocolName property";
185             }
186 
187             var params = {
188                 taskId: config.taskId,
189                 path: config.path,
190                 protocolName: config.protocolName,
191                 protocolDescription: config.protocolDescription,
192                 file: config.files,
193                 fileIds: config.fileIds,
194                 allowNonExistentFiles: config.allowNonExistentFiles,
195                 pipelineDescription: config.pipelineDescription,
196                 saveProtocol: config.saveProtocol == undefined || config.saveProtocol
197             };
198             if (config.xmlParameters)
199             {
200                 // Convert from an Element to a string if needed
201                 // params.configureXml = Ext4.DomHelper.markup(config.xmlParameters);
202                 if (typeof config.xmlParameters == "object")
203                     throw new Error('The xml configuration is deprecated, please use the jsonParameters option to specify your protocol description.');
204                 else
205                     params.configureXml = config.xmlParameters;
206             }
207             else if (config.jsonParameters)
208             {
209                 if (LABKEY.Utils.isString(config.jsonParameters))
210                 {
211                     // We already have a string
212                     params.configureJson = config.jsonParameters;
213                 }
214                 else
215                 {
216                     // Convert from JavaScript object to a string
217                     params.configureJson = LABKEY.Utils.encode(config.jsonParameters);
218                 }
219             }
220 
221             var containerPath = config.containerPath ? config.containerPath : LABKEY.ActionURL.getContainer();
222             var url = LABKEY.ActionURL.buildURL("pipeline-analysis", "startAnalysis.api", containerPath);
223             LABKEY.Ajax.request({
224                 url: url,
225                 method: 'POST',
226                 params: params,
227                 timeout: 60000000,
228                 success: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnSuccess(config), config.scope),
229                 failure: LABKEY.Utils.getCallbackWrapper(LABKEY.Utils.getOnFailure(config), config.scope, true)
230             });
231         }
232     };
233 };
234