diff --git a/OConnor/resources/views/BloodCalendar.html b/OConnor/resources/views/BloodCalendar.html index 2903e7e2..3d517e25 100644 --- a/OConnor/resources/views/BloodCalendar.html +++ b/OConnor/resources/views/BloodCalendar.html @@ -177,8 +177,13 @@ var content = document.createElement('span'); - content.innerHTML = '' + animal[i][t] + week[i][t] + ''; - + // Build the anchor with DOM APIs so list-derived values (URL, animal id, entry text) can't inject markup + var anchor = document.createElement('a'); + anchor.setAttribute('style', 'font-size:14px'); + anchor.setAttribute('href', urls[i][t]); + anchor.appendChild(document.createTextNode(animal[i][t] + week[i][t])); + content.appendChild(anchor); + row.appendChild(content); column.appendChild(row); diff --git a/OConnorExperiments/src/org/labkey/oconnorexperiments/OConnorExperimentsController.java b/OConnorExperiments/src/org/labkey/oconnorexperiments/OConnorExperimentsController.java index fd6b148c..4361fe3f 100644 --- a/OConnorExperiments/src/org/labkey/oconnorexperiments/OConnorExperimentsController.java +++ b/OConnorExperiments/src/org/labkey/oconnorexperiments/OConnorExperimentsController.java @@ -16,49 +16,29 @@ package org.labkey.oconnorexperiments; -import org.apache.commons.io.FileUtils; -import org.apache.logging.log4j.LogManager; import org.labkey.api.action.ApiResponse; import org.labkey.api.action.ApiSimpleResponse; import org.labkey.api.action.FormHandlerAction; -import org.labkey.api.action.FormViewAction; import org.labkey.api.action.ReadOnlyApiAction; -import org.labkey.api.action.ReturnUrlForm; import org.labkey.api.action.SimpleViewAction; import org.labkey.api.action.SpringActionController; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; -import org.labkey.api.data.CoreSchema; -import org.labkey.api.data.DbSequenceManager; -import org.labkey.api.data.SimpleFilter; -import org.labkey.api.data.Sort; -import org.labkey.api.data.SqlExecutor; import org.labkey.api.data.TableInfo; -import org.labkey.api.data.TableSelector; -import org.labkey.api.files.FileContentService; import org.labkey.api.portal.ProjectUrls; import org.labkey.api.query.BatchValidationException; -import org.labkey.api.query.FieldKey; -import org.labkey.api.query.QueryAction; import org.labkey.api.query.QueryService; import org.labkey.api.query.QueryUpdateService; import org.labkey.api.query.UserSchema; import org.labkey.api.security.RequiresLogin; import org.labkey.api.security.RequiresPermission; -import org.labkey.api.security.User; -import org.labkey.api.security.UserManager; -import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.security.permissions.InsertPermission; import org.labkey.api.security.permissions.ReadPermission; import org.labkey.api.security.permissions.UpdatePermission; -import org.labkey.api.services.ServiceRegistry; import org.labkey.api.util.DOM; -import org.labkey.api.util.FileStream; import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.util.Path; import org.labkey.api.util.URLHelper; -import org.labkey.api.view.ActionURL; import org.labkey.api.view.HtmlView; import org.labkey.api.view.HttpView; import org.labkey.api.view.JspView; @@ -66,18 +46,12 @@ import org.labkey.api.view.NotFoundException; import org.labkey.api.view.RedirectException; import org.labkey.api.view.VBox; -import org.labkey.api.webdav.WebdavResolver; -import org.labkey.api.webdav.WebdavResource; import org.labkey.oconnorexperiments.query.OConnorExperimentsUserSchema; import org.springframework.validation.BindException; import org.springframework.validation.Errors; import org.springframework.web.servlet.ModelAndView; -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.List; import java.util.Map; @@ -106,316 +80,6 @@ public void addNavTrail(NavTree root) } } - @RequiresPermission(AdminPermission.class) - public static class MigrateDataAction extends FormViewAction - { - @Override - public void validateCommand(UserForm target, Errors errors) - { - } - - @Override - public ModelAndView getView(UserForm form, boolean reshow, BindException errors) - { - return new JspView<>("/org/labkey/oconnorexperiments/view/migrateData.jsp"); - } - - @Override - public boolean handlePost(UserForm form, BindException errors) throws Exception - { - if (form.isFinalMigration()) - { - LogManager.getLogger(OConnorExperimentsController.class).info("Final migration to be performed - file move events will be performed (irreversible)."); - } - - // global containers - Container sourceContainer = ContainerManager.getForPath(form.getSourceProject()); - Container targetContainer = getContainer(); - FileContentService fileContentService = FileContentService.get(); - - // get table info for the source table - UserSchema sourceSchema = QueryService.get().getUserSchema(getUser(), sourceContainer, "oconnor"); - TableInfo sourceTable = sourceSchema.getTable("simple_experiment"); - TableSelector tableSelector = new TableSelector(sourceTable, null, new Sort("ExpNumber")); - Collection> sourceCollection = tableSelector.getMapCollection(); - - // get table info for target table - UserSchema targetSchema = QueryService.get().getUserSchema(getUser(), getContainer(), OConnorExperimentsSchema.NAME); - TableInfo targetTable = targetSchema.getTable(OConnorExperimentsSchema.EXPERIMENTS); - QueryUpdateService queryUpdateService = targetTable.getUpdateService(); - BatchValidationException batchErrors = new BatchValidationException(); - - TableInfo typeTable = targetSchema.getTable(OConnorExperimentsSchema.EXPERIMENT_TYPE); - QueryUpdateService typeUpdateService = typeTable.getUpdateService(); - - int maxExpNumber = 0; - - // parse the sourceCollection into the target collection - for (Map databaseMap : sourceCollection) - { - Map map = new CaseInsensitiveHashMap<>(); - map.put("ExperimentNumber", databaseMap.get("expnumber")); - int expNumber = (int) databaseMap.get("expnumber"); - if (expNumber > form.getBeginRange() && expNumber < form.getEndRange()) - { - if (expNumber > maxExpNumber) - maxExpNumber = expNumber; - map.put("Name", databaseMap.get("expnumber")); - map.put("Description", databaseMap.get("expDescription")); - - String currentType = (String) databaseMap.get("expType"); - Integer targetType = null; - if (currentType != null) - { - TableSelector typeSelector = new TableSelector(typeTable, Collections.singleton("RowId"), new SimpleFilter(FieldKey.fromParts("Name"), currentType), null); - targetType = typeSelector.getObject(Integer.class); - if (targetType == null) - { - Map newType = new CaseInsensitiveHashMap<>(); - newType.put("Name", currentType); - newType.put("Enabled", true); - List> newTypes = typeUpdateService.insertRows(getUser(), getContainer(), Collections.singletonList(newType), new BatchValidationException(), null, null); - targetType = (Integer) newTypes.get(0).get("RowId"); - } - } - - map.put("ExperimentTypeId", targetType); - //map.put("Modified", databaseMap.get("created")); - - // get the user name - User effectiveUser; - if (databaseMap.get("initials") == null) - { - effectiveUser = getUser(); - } - else - { - User user = UserManager.getUserByDisplayName((String) databaseMap.get("initials")); - if (user == null) - { - LogManager.getLogger(OConnorExperimentsController.class).warn("User '" + databaseMap.get("initials") + "' not found for experiment " + databaseMap.get("expnumber")); - effectiveUser = getUser(); - } - else - { - effectiveUser = user; - } - } - - databaseMap.put("EffectiveUser", effectiveUser); - LogManager.getLogger(OConnorExperimentsController.class).info("Insert on experiment " + databaseMap.get("expnumber")); - List> updateResult; - try - { - updateResult = queryUpdateService.insertRows(getUser(), getContainer(), Collections.singletonList(map), batchErrors, null, null); - } - catch (Exception e) - { - // log the error to the logfile and continue - LogManager.getLogger(OConnorExperimentsController.class).warn("Error inserting expNumber " + expNumber + " with exception " + e.getMessage()); - continue; - } - if (batchErrors.hasErrors()) - { - // throw batchErrors.getLastRowError(); - LogManager.getLogger(OConnorExperimentsController.class).warn("Error inserting expNumber " + expNumber); - } - - Container workbookContainer = ContainerManager.getForId((String)updateResult.get(0).get("EntityId")); - databaseMap.put("ContainerObj", workbookContainer); - databaseMap.put("ContainerStr", updateResult.get(0).get("EntityId")); - - // We don't want these fields to be spoofable through the QueryUpdateService (and hence the Client API), - // so preserve the value from the source data manually - Date created = (Date)databaseMap.get("created"); - new SqlExecutor(CoreSchema.getInstance().getSchema()).execute("UPDATE core.containers SET CreatedBy = ?, Created = ? WHERE RowId = ?", effectiveUser.getUserId(), created, workbookContainer.getRowId()); - - // Move files - File sourceFile = new File(fileContentService.getFileRoot(sourceContainer).getPath() + File.separator + "@files", databaseMap.get("expnumber").toString()); - File targetDir = new File(fileContentService.getFileRoot(targetContainer).getPath() + File.separator + databaseMap.get("expnumber").toString() + File.separator + "@files"); - LogManager.getLogger(OConnorExperimentsController.class).info("Copy from file '" + sourceFile + "' to directory '" + targetDir +"'" ); - if (sourceFile.exists()) - { - FileUtils.copyDirectory(sourceFile, targetDir); - // only fire the File Move Event if this is a final migration - it is difficult to reverse - if (form.isFinalMigration()) - { - fileContentService.fireFileMoveEvent(sourceFile, targetDir, effectiveUser, getContainer()); - } - } - } - } - - // - // 2nd pass - update all ParentExperiment fields - // - for (Map databaseMap : sourceCollection) - { - int expNumber = (int) databaseMap.get("expnumber"); - if (expNumber > form.getBeginRange() && expNumber < form.getEndRange()) - { - Map map = new CaseInsensitiveHashMap<>(); - map.put("container", databaseMap.get("ContainerStr")); - - String[] parents; - ArrayList parentsEntityId = new ArrayList<>(); - if (databaseMap.get("expParent") != null) - { - String parentString = databaseMap.get("expParent").toString(); - parents = parentString.split("[\\s,;&]+"); - // get Container for SortOrder - for ( int i =0; i< parents.length; i++) - { - if ( ! parents[i].equalsIgnoreCase("and")) - { - Container child = targetContainer.getChild(parents[i]); - if (child != null) - { - parentsEntityId.add( child.getEntityId().toString() ); - } - else - { - LogManager.getLogger(OConnorExperimentsController.class).warn("child container not found: " + parents[i] + " for experiment " + databaseMap.get("expnumber") + " with username " + databaseMap.get("initials")); - } - } - } - if (!parentsEntityId.isEmpty()) - { - map.put("ParentExperiments", parentsEntityId.toArray(new String[0])); - - // workaround, pass user, container - databaseMap.get("Container"), singleton list - LogManager.getLogger(OConnorExperimentsController.class).info("Update rows on experiment " + databaseMap.get("expnumber")); - try - { - queryUpdateService.updateRows(getUser(), targetContainer, Collections.singletonList(map), null, null, null); - } - catch (Exception e) - { - // log the error to the logfile and continue - LogManager.getLogger(OConnorExperimentsController.class).warn("Error updating parent experiments for experiment number " + expNumber + " with exception " + e.getMessage()); - continue; - } - - } - } - } - } - - // - // 3rd pass update the wiki, done seperately so that the cache is not modified - // - for (Map databaseMap : sourceCollection) - { - int expNumber = (int) databaseMap.get("expnumber"); - if (expNumber > form.getBeginRange() && expNumber < form.getEndRange()) - { - - // Update the existing Wiki content with the value from the old table, if present - String wikiText = (String)databaseMap.get("expcomments"); - if (wikiText != null) - { - User user = UserManager.getUserByDisplayName((String) databaseMap.get("initials")); - User effectiveUser = user == null ? getUser() : user; - Container workbookContainer = targetContainer.getChild(databaseMap.get("expnumber").toString()); - if (workbookContainer == null) - { - LogManager.getLogger(OConnorExperimentsController.class).warn("Updating wiki, container not found: " + databaseMap.get("expnumber")); - } - else - { - Path path = new Path("_webdav").append(workbookContainer.getParsedPath()).append("@wiki", "default", "default.html"); - WebdavResolver resolver = ServiceRegistry.get(WebdavResolver.class); - WebdavResource resource = resolver.lookup(path); - - FileStream.StringFileStream in = new FileStream.StringFileStream(wikiText); - try - { - resource.copyFrom(effectiveUser, in); - } - catch (Exception e) - { - // log the error to the logfile and continue - LogManager.getLogger(OConnorExperimentsController.class).warn("Error wiki for experiment number " + expNumber + " with exception " + e.getMessage()); - continue; - } - finally - { - in.closeInputStream(); - } - LogManager.getLogger(OConnorExperimentsController.class).info("Inserting wiki for experiment " + databaseMap.get("expnumber")); - } - } - } - } - - // we need to leave the target location set up correctly so that the next experiment that's created gets the next value in the sequence - DbSequenceManager.get(targetContainer, ContainerManager.WORKBOOK_DBSEQUENCE_NAME).ensureMinimum(maxExpNumber); - - return true; - } - - @Override - public void addNavTrail(NavTree root) - { - } - - @Override - public ActionURL getSuccessURL(UserForm form) - { - UserSchema targetSchema = QueryService.get().getUserSchema(getUser(), getContainer(), OConnorExperimentsSchema.NAME); - return targetSchema.getQueryDefForTable(OConnorExperimentsSchema.EXPERIMENTS).urlFor(QueryAction.executeQuery); - } - } - - public static class UserForm extends ReturnUrlForm - { - private String _sourceProject; - private int _beginRange; - private int _endRange; - private boolean _finalMigration; - - public String getSourceProject() - { - return _sourceProject; - } - - public void setSourceProject(String sourceProject) - { - _sourceProject = sourceProject; - } - - public int getBeginRange() - { - return _beginRange; - } - - public void setBeginRange(int beginRange) - { - _beginRange = beginRange; - } - - public int getEndRange() - { - return _endRange; - } - - public void setEndRange(int endRange) - { - _endRange = endRange; - } - - public boolean isFinalMigration() - { - return _finalMigration; - } - - public void setFinalMigration(boolean finalMigration) - { - _finalMigration = finalMigration; - } - } - - /** * Use the QueryUpdateService to create a new experiment so the Experiment and Workbook defaults are used * then redirect to the newly created experiment begin page. diff --git a/OConnorExperiments/src/org/labkey/oconnorexperiments/view/migrateData.jsp b/OConnorExperiments/src/org/labkey/oconnorexperiments/view/migrateData.jsp deleted file mode 100644 index 9bacb186..00000000 --- a/OConnorExperiments/src/org/labkey/oconnorexperiments/view/migrateData.jsp +++ /dev/null @@ -1,41 +0,0 @@ -<% -/* - * Copyright (c) 2005-2014 Fred Hutchinson Cancer Research Center - * - * 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. - */ -%> -<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %> -<%@ page import="org.labkey.oconnorexperiments.OConnorExperimentsController"%> -<%@ page extends="org.labkey.api.jsp.JspBase" %> - -
> -

OConnor Experiments to Workbooks data migration

-<%=formatMissedErrorsInTable("form", 2)%> - - - - - - - - - - - - - - - -
Source Project Name:
Experiment Number Range: -
Final Migration:
<%= button("Submit").submit(true) %>
- diff --git a/genotyping/src/org/labkey/genotyping/GenotypingController.java b/genotyping/src/org/labkey/genotyping/GenotypingController.java index f215fab6..dfabbd10 100644 --- a/genotyping/src/org/labkey/genotyping/GenotypingController.java +++ b/genotyping/src/org/labkey/genotyping/GenotypingController.java @@ -25,7 +25,6 @@ import org.labkey.api.action.FormHandlerAction; import org.labkey.api.action.FormViewAction; import org.labkey.api.action.HasViewContext; -import org.labkey.api.action.MutatingApiAction; import org.labkey.api.action.QueryViewAction; import org.labkey.api.action.QueryViewAction.QueryExportForm; import org.labkey.api.action.ReturnUrlForm; @@ -40,9 +39,11 @@ import org.labkey.api.assay.actions.AssayRunsAction; import org.labkey.api.assay.actions.BaseAssayAction; import org.labkey.api.assay.actions.ProtocolIdForm; +import org.labkey.api.audit.AuditLogService; +import org.labkey.api.audit.AuditTypeEvent; +import org.labkey.api.audit.provider.ContainerAuditProvider; import org.labkey.api.data.ActionButton; import org.labkey.api.data.ButtonBar; -import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; import org.labkey.api.data.DataRegion; import org.labkey.api.data.DataRegionSelection; @@ -66,19 +67,14 @@ import org.labkey.api.pipeline.PipelineValidationException; import org.labkey.api.pipeline.browse.PipelinePathForm; import org.labkey.api.portal.ProjectUrls; -import org.labkey.api.query.CustomView; import org.labkey.api.query.FieldKey; import org.labkey.api.query.QueryService; import org.labkey.api.query.QuerySettings; import org.labkey.api.query.QueryView; import org.labkey.api.query.UserSchema; -import org.labkey.api.security.CSRF; import org.labkey.api.security.IgnoresTermsOfUse; -import org.labkey.api.security.RequiresNoPermission; import org.labkey.api.security.RequiresPermission; import org.labkey.api.security.User; -import org.labkey.api.security.UserManager; -import org.labkey.api.security.ValidEmail; import org.labkey.api.security.permissions.AdminPermission; import org.labkey.api.security.permissions.DeletePermission; import org.labkey.api.security.permissions.InsertPermission; @@ -88,13 +84,11 @@ import org.labkey.api.util.FileUtil; import org.labkey.api.util.MinorConfigurationException; import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.util.Pair; import org.labkey.api.util.URLHelper; import org.labkey.api.util.logging.LogHelper; import org.labkey.api.view.ActionURL; import org.labkey.api.view.DataView; import org.labkey.api.view.DetailsView; -import org.labkey.api.view.HttpView; import org.labkey.api.view.JspView; import org.labkey.api.view.NavTree; import org.labkey.api.view.NotFoundException; @@ -105,9 +99,6 @@ import org.labkey.api.view.template.PageConfig; import org.labkey.genotyping.GenotypingManager.SEQUENCE_PLATFORMS; import org.labkey.genotyping.GenotypingQuerySchema.TableType; -import org.labkey.genotyping.galaxy.GalaxyFolderSettings; -import org.labkey.genotyping.galaxy.GalaxyManager; -import org.labkey.genotyping.galaxy.GalaxyUserSettings; import org.labkey.genotyping.sequences.FastqGenerator; import org.labkey.genotyping.sequences.FastqWriter; import org.labkey.genotyping.sequences.SequenceManager; @@ -121,24 +112,18 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.PrintWriter; -import java.math.BigInteger; -import java.net.MalformedURLException; -import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; -import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; @@ -352,6 +337,13 @@ public boolean handlePost(MatchesForm form, BindException errors) try { _count = GenotypingManager.get().deleteMatches(getContainer(), getUser(), form.getAnalysis(), matchIds); + + if (_count > 0) + { + AuditTypeEvent event = new AuditTypeEvent(ContainerAuditProvider.CONTAINER_AUDIT_EVENT, getContainer(), + "Deleted " + _count + " genotyping match(es) from analysis " + form.getAnalysis() + ": " + matchIds); + AuditLogService.get().addEvent(getUser(), event); + } } catch (IllegalStateException e) { @@ -396,9 +388,8 @@ public URLHelper getSuccessURL(ReturnUrlForm form) // TODO: Annotate getters with @Nullable - public static class AdminForm extends ReturnUrlForm implements GenotypingFolderSettings, GalaxyFolderSettings, HasViewContext + public static class AdminForm extends ReturnUrlForm implements GenotypingFolderSettings, HasViewContext { - private String _galaxyURL; private String _sequencesQuery; private String _runsQuery; private String _samplesQuery; @@ -415,9 +406,6 @@ public void setViewContext(ViewContext context) _runsQuery = genotypingSettings.getRunsQuery(); _samplesQuery = genotypingSettings.getSamplesQuery(); _haplotypesQuery = genotypingSettings.getHaplotypesQuery(); - - GalaxyFolderSettings galaxySettings = GalaxyManager.get().getSettings(c); - _galaxyURL = galaxySettings.getGalaxyURL(); } @Override @@ -426,18 +414,6 @@ public ViewContext getViewContext() throw new IllegalStateException(); } - @Override - public @Nullable String getGalaxyURL() - { - return _galaxyURL; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setGalaxyURL(@Nullable String galaxyURL) - { - _galaxyURL = galaxyURL; - } - @Override public @Nullable String getSequencesQuery() { @@ -521,20 +497,6 @@ public class AdminAction extends FormViewAction @Override public void validateCommand(AdminForm form, Errors errors) { - String galaxyUrl = form.getGalaxyURL(); - - // Allow null, #11130 - if (null != galaxyUrl) - { - try - { - new URL(galaxyUrl); - } - catch (MalformedURLException e) - { - errors.reject(ERROR_MSG, "Invalid Galaxy URL"); - } - } } @Override @@ -562,7 +524,6 @@ public boolean handlePost(AdminForm form, BindException errors) { // Save both the genotyping settings and Galaxy configuration settings GenotypingManager.get().saveSettings(getContainer(), form); - GalaxyManager.get().saveSettings(getContainer(), form); return true; } @@ -656,124 +617,11 @@ public void setZipFileName(String zipFileName) } } - public static class MySettingsForm extends ReturnUrlForm implements GalaxyUserSettings, HasViewContext - { - private String _galaxyKey; - - @Override - public void setViewContext(ViewContext context) - { - Container c = context.getContainer(); - User user = context.getUser(); - GalaxyUserSettings settings = GalaxyManager.get().getUserSettings(c, user); - _galaxyKey = settings.getGalaxyKey(); - } - - @Override - public ViewContext getViewContext() - { - throw new IllegalStateException(); - } - - @Override - public String getGalaxyKey() - { - return _galaxyKey; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setGalaxyKey(String galaxyKey) - { - _galaxyKey = galaxyKey; - } - } - - - public static ActionURL getMySettingsURL(Container c, ActionURL returnUrl) - { - ActionURL url = new ActionURL(MySettingsAction.class, c); - url.addReturnUrl(returnUrl); - return url; - } - - - @RequiresPermission(ReadPermission.class) - public static class MySettingsAction extends FormViewAction - { - @Override - public void validateCommand(MySettingsForm form, Errors errors) - { - String key = form.getGalaxyKey(); - - if (null == key) - { - errors.reject(ERROR_MSG, "Please provide a Galaxy web API key. To generate this, log into your Galaxy server and visit User -> Preferences -> Manage your information."); - } - else - { - key = key.trim(); - String advice = " Please copy the web API key from your Galaxy server account (User -> Preferences -> Manage your information) and paste it below."; - - if (key.length() != 32) - { - errors.reject(ERROR_MSG, "Galaxy web API key is the wrong length." + advice); - } - else - { - boolean success = false; - - try - { - BigInteger bi = new BigInteger(key, 16); - String hex = bi.toString(16); - - if (hex.equalsIgnoreCase(key)) - success = true; - } - catch (NumberFormatException e) - { - // Error below - } - - if (!success) - errors.reject(ERROR_MSG, "Galaxy web API key is not valid hexadecimal." + advice); - } - } - } - - @Override - public ModelAndView getView(MySettingsForm form, boolean reshow, BindException errors) - { - return new JspView<>("/org/labkey/genotyping/view/mySettings.jsp", form, errors); - } - - @Override - public boolean handlePost(MySettingsForm form, BindException errors) - { - GalaxyManager.get().saveUserSettings(getContainer(), getUser(), form); - return true; - } - - @Override - public URLHelper getSuccessURL(MySettingsForm form) - { - return form.getReturnUrlHelper(); - } - - @Override - public void addNavTrail(NavTree root) - { - root.addChild("My Galaxy Settings"); - } - } - - public static class ImportReadsForm extends PipelinePathForm { private String _readsPath; private Integer _run; private Integer _metaDataRun = null; - private boolean _analyze = false; private boolean _pipeline = false; private String _platform; private String _prefix; @@ -842,17 +690,6 @@ public void setMetaDataRun(Integer metaDataRun) _metaDataRun = metaDataRun; } - public boolean getAnalyze() - { - return _analyze; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setAnalyze(boolean analyze) - { - _analyze = analyze; - } - public boolean getPipeline() { return _pipeline; @@ -995,9 +832,7 @@ public boolean handlePost(ImportReadsForm form, BindException errors) throws Exc return true; } - // Successful submission via the UI... redirect either to the pipeline status grid or analyze action - ActionURL pipelineURL = PageFlowUtil.urlProvider(PipelineUrls.class).urlBegin(getContainer()); - _successURL = form.getAnalyze() ? getAnalyzeURL(form.getRun(), pipelineURL) : pipelineURL; + _successURL = PageFlowUtil.urlProvider(PipelineUrls.class).urlBegin(getContainer()); return true; } @@ -1061,327 +896,6 @@ public void addNavTrail(NavTree root) } - public static class AnalyzeForm extends ReturnUrlForm - { - private int _run; - private String _sequencesView; - private String _description; - private String _samples; - - public int getRun() - { - return _run; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setRun(int run) - { - _run = run; - } - - public String getSequencesView() - { - return _sequencesView; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setSequencesView(String sequencesView) - { - _sequencesView = sequencesView; - } - - public String getDescription() - { - return _description; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setDescription(String description) - { - _description = description; - } - - public String getSamples() - { - return _samples; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setSamples(String samples) - { - _samples = samples; - } - } - - - private ActionURL getAnalyzeURL(int runId, ActionURL cancelURL) - { - ActionURL url = new ActionURL(AnalyzeAction.class, getContainer()); - url.addParameter("run", runId); - url.addReturnUrl(cancelURL); - return url; - } - - - @RequiresPermission(InsertPermission.class) - public static class AnalyzeAction extends FormViewAction - { - @Override - public void validateCommand(AnalyzeForm target, Errors errors) - { - } - - @Override - public ModelAndView getView(AnalyzeForm form, boolean reshow, BindException errors) throws Exception - { - GenotypingRun run = GenotypingManager.get().getRun(getContainer(), form.getRun()); - - // Verify that galaxy properties are set before submitting job. This will throw NotFoundException if either URL or web API key isn't set. - // 12.1: relax this requirement... allow users to submit jobs without a galaxy server configured or available - //GalaxyUtils.get(getContainer(), getUser()); - - SortedSet views = new TreeSet<>((c1, c2) -> - { - String name1 = c1.getName(); - String name2 = c2.getName(); - - return (null == name1 ? DEFAULT_VIEW_PLACEHOLDER : name1).compareTo((null == name2 ? DEFAULT_VIEW_PLACEHOLDER : name2)); - }); - GenotypingSchema gs = GenotypingSchema.get(); - views.addAll(QueryService.get().getCustomViews(getUser(), getContainer(), getUser(), gs.getSchemaName(), gs.getSequencesTable().getName(), false)); - - Map> sampleMap = new TreeMap<>(); - - try (Results results = SampleManager.get().selectSamples(getContainer(), getUser(), run, "library_sample_name, library_sample_species, key", "creating an analysis")) - { - Map fieldMap = results.getFieldMap(); - ColumnInfo sampleNameColumn = getColumnInfo(fieldMap, "library_sample_name"); - ColumnInfo sampleSpeciesColumn = getColumnInfo(fieldMap, "library_sample_species"); - ColumnInfo keyColumn = getColumnInfo(fieldMap, "key"); - - while (results.next()) - { - String sampleName = (String) sampleNameColumn.getValue(results); - String species = (String) sampleSpeciesColumn.getValue(results); - int sampleId = (Integer) keyColumn.getValue(results); - sampleMap.put(sampleId, new Pair<>(sampleName, species)); - } - } - - return new JspView<>("/org/labkey/genotyping/view/analyze.jsp", new AnalyzeBean(views, sampleMap, form.getReturnActionURL()), errors); - } - - // Throws NotFoundException if column doesn't exist - private ColumnInfo getColumnInfo(Map fieldMap, String columnName) - { - ColumnInfo column = fieldMap.get(FieldKey.fromString(columnName)); - - if (null == column) - throw new NotFoundException("Expected to find a column named \"" + columnName + "\" in the samples query"); - - return column; - } - - @Override - public boolean handlePost(AnalyzeForm form, BindException errors) throws Exception - { - GenotypingRun run = GenotypingManager.get().getRun(getContainer(), form.getRun()); - if (run == null) - { - errors.rejectValue("run", ERROR_MSG, "No run found"); - return false; - } - - PipeRoot root = PipelineService.get().findPipelineRoot(getContainer()); - - FileLike readsFile = run.getWorkingDir().resolveChild(run.getFileName()); - ViewBackgroundInfo vbi = new ViewBackgroundInfo(getContainer(), getUser(), getViewContext().getActionURL()); - - String sequencesViewName = form.getSequencesView(); - String description = form.getDescription(); - String sequencesView = DEFAULT_VIEW_PLACEHOLDER.equals(sequencesViewName) ? null : sequencesViewName; - String samples = form.getSamples(); - if(samples == null) - { - errors.reject(ERROR_MSG, "Must provide a list of sample IDs"); - return false; - } - - Set sampleKeys; - String[] keys = samples.split(","); - sampleKeys = new HashSet<>(keys.length); - - for (String key : keys) - sampleKeys.add(Integer.parseInt(key)); - - GenotypingAnalysis analysis = GenotypingManager.get().createAnalysis(getContainer(), getUser(), run, description, sequencesView); - try - { - PipelineJob analysisJob = new SubmitAnalysisJob(vbi, root, readsFile, analysis, sampleKeys); - PipelineService.get().queueJob(analysisJob); - } - catch (MinorConfigurationException e) - { - errors.reject(ERROR_MSG, e.getMessage()); - return false; - } - - return true; - } - - @Override - public URLHelper getSuccessURL(AnalyzeForm analyzeForm) - { - return PageFlowUtil.urlProvider(PipelineUrls.class).urlBegin(getContainer()); - } - - @Override - public void addNavTrail(NavTree root) - { - root.addChild("Submit Analysis"); - } - } - - - public static class AnalyzeBean - { - private final SortedSet _sequencesViews; - private final Map> _sampleMap; - private final ActionURL _returnUrl; - - private AnalyzeBean(SortedSet sequenceViews, Map> sampleMap, ActionURL returnUrl) - { - _sequencesViews = sequenceViews; - _sampleMap = sampleMap; - _returnUrl = returnUrl; - } - - public SortedSet getSequencesViews() - { - return _sequencesViews; - } - - public Map> getSampleMap() - { - return _sampleMap; - } - - public ActionURL getReturnUrl() - { - return _returnUrl; - } - } - - - public static ActionURL getWorkflowCompleteURL(Container c, GenotypingAnalysis analysis) - { - ActionURL url = new ActionURL(WorkflowCompleteAction.class, c); - url.addParameter("analysis", analysis.getRowId()); - url.addParameter("path", analysis.getPath()); - return url; - } - - - @RequiresNoPermission - @CSRF(CSRF.Method.NONE) - public class WorkflowCompleteAction extends MutatingApiAction - { - @Override - public void validateForm(ImportAnalysisForm form, Errors errors) - { - if (null == form.getAnalysis()) - errors.reject(ERROR_MSG, "Must specify an analysis parameter"); - - if (null == form.getPath()) - errors.reject(ERROR_MSG, "Must specify a path parameter"); - } - - @Override - public Object execute(ImportAnalysisForm form, BindException errors) throws Exception - { - LOG.info("Galaxy signaled the completion of analysis " + form.getAnalysis()); - String message; - - // Send any exceptions back to the Galaxy task so it can log it as well. - String FAILURE_PREFACE = "Failed to queue import analysis job: "; - - try - { - FileLike analysisDir = FileSystemLike.getVerifiedFileLike(getContainer(), form.getPath()); - int analysisId = form.getAnalysis(); - - User user = getUser(); - if (user.isGuest()) - { - Properties props = GenotypingManager.get().readProperties(analysisDir); - String email = (String)props.get("user"); - - if (null != email) - { - // Possible that user doesn't exist or changed email (e.g., re-loading an old analysis) - User test = UserManager.getUser(new ValidEmail(email)); - - if (null != test) - user = test; - } - } - - importAnalysis(analysisId, analysisDir, user); - message = "Import analysis job queued at " + new Date(); - } - catch (FileNotFoundException fnf) - { - // Send back a vague, generic message in the case of all file-not-found-type problems, e.g., specified path is - // missing, isn't a directory, lacks a properties.xml file, or doesn't match the analysis table path. This - // prevents attackers from gaining any useful information about the file system. Log the more detailed message. - message = FAILURE_PREFACE + "Analysis path doesn't match import path (see system log for more details)"; - - // But log more detail to the administrator so they're aware - LOG.error(FAILURE_PREFACE + fnf.getMessage()); - } - catch (Exception e) - { - message = FAILURE_PREFACE + e.getMessage(); - LOG.error(message); - } - - // Plain text response back to Galaxy - sendPlainText(message); - - return null; - } - } - - - public static class ImportAnalysisForm - { - private Integer _analysis = null; - private String _path = null; - - public Integer getAnalysis() - { - return _analysis; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setAnalysis(Integer analysis) - { - _analysis = analysis; - } - - public String getPath() - { - return _path; - } - - @SuppressWarnings({"UnusedDeclaration"}) - public void setPath(String path) - { - _path = path; - } - } - - @RequiresPermission(InsertPermission.class) public class ImportAnalysisAction extends FormHandlerAction { @@ -1838,47 +1352,22 @@ public ModelAndView getView(RunForm form, BindException errors) throws Exception if (null == _run) throw new NotFoundException("Run not found"); - final boolean allowAnalysis = GenotypingManager.SEQUENCE_PLATFORMS.LS454.toString().equals(_run.getPlatform()); - - ModelAndView readsView; - readsView = super.getView(form, errors); + ModelAndView readsView = super.getView(form, errors); // Just return the view in export case if (form.isExport()) return readsView; VBox vbox = new VBox(); - final ActionButton submitAnalysis = new ActionButton("Add Analysis", getAnalyzeURL(_run.getRowId(), getViewContext().getActionURL())); if (GenotypingManager.get().hasAnalyses(_run)) { - GenotypingAnalysesView analyses = new GenotypingAnalysesView(getViewContext(), null, "Analyses", new SimpleFilter(FieldKey.fromParts("Run"), _run.getRowId()), false) { - @Override - protected void populateButtonBar(DataView view, ButtonBar bar) - { - bar.add(submitAnalysis); - } - }; + GenotypingAnalysesView analyses = new GenotypingAnalysesView(getViewContext(), null, "Analyses", new SimpleFilter(FieldKey.fromParts("Run"), _run.getRowId()), false); analyses.setButtonBarPosition(DataRegion.ButtonBarPosition.TOP); analyses.setTitle("Analyses"); analyses.setTitleHref(getAnalysesURL(getContainer())); vbox.addView(analyses); } - else - { - vbox.addView(new HttpView() { - @Override - protected void renderInternal(Object model, PrintWriter out) throws Exception - { - if(allowAnalysis) - { - submitAnalysis.render(new RenderContext(getViewContext()), out); - out.println("

"); - } - } - }); - } - vbox.addView(readsView); return vbox; @@ -1924,6 +1413,13 @@ public boolean handlePost(Object o, BindException errors) gm.deleteRun(run); } + if (!runs.isEmpty()) + { + AuditTypeEvent event = new AuditTypeEvent(ContainerAuditProvider.CONTAINER_AUDIT_EVENT, getContainer(), + "Deleted " + runs.size() + " genotyping run(s): " + runs); + AuditLogService.get().addEvent(getUser(), event); + } + return true; } @@ -1947,13 +1443,21 @@ public void validateCommand(Object target, Errors errors) public boolean handlePost(Object o, BindException errors) throws Exception { GenotypingManager gm = GenotypingManager.get(); + Set analysisIds = DataRegionSelection.getSelectedIntegers(getViewContext(), true); - for (Integer analysisId : DataRegionSelection.getSelectedIntegers(getViewContext(), true)) + for (Integer analysisId : analysisIds) { GenotypingAnalysis analysis = gm.getAnalysis(getContainer(), analysisId); gm.deleteAnalysis(analysis); } + if (!analysisIds.isEmpty()) + { + AuditTypeEvent event = new AuditTypeEvent(ContainerAuditProvider.CONTAINER_AUDIT_EVENT, getContainer(), + "Deleted " + analysisIds.size() + " genotyping analysis/analyses: " + analysisIds); + AuditLogService.get().addEvent(getUser(), event); + } + return true; } diff --git a/genotyping/src/org/labkey/genotyping/SubmitAnalysisJob.java b/genotyping/src/org/labkey/genotyping/SubmitAnalysisJob.java deleted file mode 100644 index f0102063..00000000 --- a/genotyping/src/org/labkey/genotyping/SubmitAnalysisJob.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2010-2018 LabKey Corporation - * - * 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. - */ -package org.labkey.genotyping; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.apache.commons.lang3.mutable.MutableInt; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.labkey.api.data.SimpleFilter; -import org.labkey.api.data.TSVWriter; -import org.labkey.api.data.Table; -import org.labkey.api.data.TableInfo; -import org.labkey.api.data.TableSelector; -import org.labkey.api.pipeline.PipeRoot; -import org.labkey.api.pipeline.PipelineJob; -import org.labkey.api.query.FieldKey; -import org.labkey.api.settings.AppProps; -import org.labkey.api.util.FileUtil; -import org.labkey.api.util.MinorConfigurationException; -import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.util.URLHelper; -import org.labkey.api.view.NotFoundException; -import org.labkey.api.view.ViewBackgroundInfo; -import org.labkey.genotyping.galaxy.GalaxyServer; -import org.labkey.genotyping.galaxy.GalaxyUtils; -import org.labkey.genotyping.galaxy.WorkflowCompletionMonitor; -import org.labkey.genotyping.sequences.SequenceManager; -import org.labkey.vfs.FileLike; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -/** - * User: adam - * Date: Sep 10, 2010 - * Time: 9:43:21 PM - */ -public class SubmitAnalysisJob extends PipelineJob -{ - private final FileLike _dir; - private final GenotypingAnalysis _analysis; - private final FileLike _analysisDir; - private final Set _sampleIds; - - private URLHelper _galaxyURL = null; - private FileLike _completionFile = null; // Used for dev mode only - - // In dev mode only, we'll test the ability to connect to the Galaxy server once; if this connection fails, we'll - // skip trying to submit to Galaxy on subsequent attempts (until server restart). - private static Boolean _useGalaxy = null; - - @JsonCreator - protected SubmitAnalysisJob( - @JsonProperty("_dir") FileLike dir, - @JsonProperty("_analysis") GenotypingAnalysis analysis, - @JsonProperty("_analysisDir") FileLike analysisDir, - @JsonProperty("_sampleIds") Set sampleIds, - @JsonProperty("_galaxyURL") URLHelper galaxyURL, - @JsonProperty("_completionFile") FileLike completionFile, - @JsonProperty("_useGalaxy") Boolean useGalaxy - ) - { - _dir = dir; - _analysis = analysis; - _analysisDir = analysisDir; - _sampleIds = sampleIds; - _galaxyURL = galaxyURL; - _completionFile = completionFile; - _useGalaxy = useGalaxy; - } - - public SubmitAnalysisJob(ViewBackgroundInfo info, PipeRoot root, FileLike reads, GenotypingAnalysis analysis, @NotNull Set sampleIds) - { - super("Submit Analysis", info, root); // No pipeline provider - _dir = reads.getParent(); - _analysis = analysis; - _sampleIds = sampleIds; - - _analysisDir = _dir.resolveChild("analysis_" + _analysis.getRowId()); - - if (_analysisDir.exists()) - throw new MinorConfigurationException("Analysis directory already exists: " + _analysisDir.getPath()); - - try - { - _analysisDir.mkdir(); - } - catch(IOException e) - { - throw new MinorConfigurationException("Can't create analysis directory: " + _analysisDir.getPath()); - } - - setLogFile(_analysisDir.resolveChild(FileUtil.makeFileNameWithTimestamp("submit_analysis", "log")).toNioPathForWrite()); - info("Creating analysis directory: " + _analysisDir.getName()); - _analysis.setPath(FileUtil.getAbsolutePath(_analysisDir.toNioPathForRead())); - _analysis.setFileName(_analysisDir.getName()); - Table.update(getUser(), GenotypingSchema.get().getAnalysesTable(), PageFlowUtil.map("Path", _analysis.getPath(), "FileName", _analysis.getFileName()), _analysis.getRowId()); - } - - - @Override - public URLHelper getStatusHref() - { - return _galaxyURL; - } - - - @Override - public String getDescription() - { - return "Submit genotyping analysis " + _analysis.getRowId(); - } - - - @Override - public void run() - { - try - { - // Do this first to ensure that the Galaxy server is configured properly and the user has set a web API key - info("Verifying Galaxy configuration"); - GalaxyServer server = null; - - try - { - server = GalaxyUtils.get(getContainer(), getUser()); - } - catch (NotFoundException e) - { - warn("Can't submit to Galaxy server: " + e.getMessage()); - } - - writeAnalysisSamples(); - writeReads(); - writeProperties(server); - writeFasta(); - sendFilesToGalaxy(server); - monitorCompletion(); - if (!GenotypingManager.get().updateAnalysisStatus(_analysis, getUser(), Status.NotSubmitted, Status.Submitted)) - throw new IllegalStateException("Analysis status should be \"NotSubmitted\""); - info("Submitting genotyping analysis job complete"); - setStatus(TaskStatus.complete); - } - catch (Exception e) - { - error("Submitting genotyping analysis failed", e); - setStatus(TaskStatus.error); - } - } - - - private void writeAnalysisSamples() - { - Map sampleMap = new HashMap<>(); // Map to reuse for each insertion to AnalysisSamples - sampleMap.put("analysis", _analysis.getRowId()); - - for (Integer sampleId : _sampleIds) - { - sampleMap.put("sampleId", sampleId); - Table.insert(getUser(), GenotypingSchema.get().getAnalysisSamplesTable(), sampleMap); - } - } - - - private void writeReads() throws IOException - { - info("Writing reads file"); - setStatus("WRITING READS"); - - // Need a custom writer since TSVGridWriter does not work in background threads - try (TSVWriter writer = new TSVWriter() { - @Override - protected int write() - { - _pw.println("name\tsample\tsequence\tquality"); - - TableInfo ti = GenotypingSchema.get().getReadsTable(); - SimpleFilter filter = new SimpleFilter(FieldKey.fromParts("run"), _analysis.getRun()); - filter.addInClause(FieldKey.fromParts("SampleId"), _sampleIds); - MutableInt rows = new MutableInt(); - - new TableSelector(ti, ti.getColumns("name,sampleid,sequence,quality"), filter, null).forEach(rs -> { - _pw.println(rs.getString(1) + "\t" + rs.getInt(2) + "\t" + rs.getString(3) + "\t" + rs.getString(4)); - rows.increment(); - }); - - return rows.getValue(); - } - }) - { - writer.write(_analysisDir.resolveChild("reads.txt").toNioPathForWrite().toFile()); - } - } - - - private void writeProperties(@Nullable GalaxyServer server) throws IOException - { - info("Writing properties file"); - setStatus("WRITING PROPERTIES"); - Properties props = new Properties(); - props.put("url", GenotypingController.getWorkflowCompleteURL(getContainer(), _analysis).getURIString()); - props.put("dir", _analysisDir.getName()); - props.put("analysis", String.valueOf(_analysis.getRowId())); - props.put("user", getUser().getEmail()); - - // Tell Galaxy "workflow complete" task to write a file when the workflow is done. In many dev mode configurations - // the Galaxy server can't communicate via HTTP with LabKey Server, so watch for this file as a backup plan. - if (AppProps.getInstance().isDevMode() || null == server) - { - _completionFile = _analysisDir.resolveChild("analysis_complete.txt"); - - if (_completionFile.exists()) - throw new IllegalStateException("Completion file already exists: " + _completionFile.getPath()); - - props.put("completionFilename", _completionFile.getName()); - } - - GenotypingManager.get().writeProperties(props, _analysisDir); - } - - - private void writeFasta() throws IOException, SQLException - { - info("Writing FASTA file"); - setStatus("WRITING FASTA"); - File fastaFile = _analysisDir.resolveChild(GenotypingManager.SEQUENCES_FILE_NAME).toNioPathForWrite().toFile(); - SequenceManager.get().writeFasta(getContainer(), getUser(), _analysis.getSequencesView(), fastaFile); - } - - - private void sendFilesToGalaxy(GalaxyServer server) throws IOException, URISyntaxException - { - if (!shouldUseGalaxy(server)) - return; - - info("Sending files to Galaxy"); - setStatus("SENDING TO GALAXY"); - - try - { - GalaxyServer.DataLibrary library = server.createLibrary(_dir.getName() + "_" + _analysis.getRowId(), "MHC analysis " + _analysis.getRowId() + " for run " + _analysis.getRun(), "An MHC genotyping analysis"); - GalaxyServer.Folder root = library.getRootFolder(); - root.uploadFromImportDirectory(_dir.getName() + "/" + _analysisDir.getName(), "txt", null, true); - - _galaxyURL = library.getURL(); - - // Hack for testing without invoking the entire galaxy workflow: if it exists, link the matches.txt file - // in /matches into the data library. - if (AppProps.getInstance().isDevMode()) - { - FileLike matchesDir = _dir.resolveChild("matches"); - - if (matchesDir.exists()) - { - FileLike matchesFile = matchesDir.resolveChild(GenotypingManager.MATCHES_FILE_NAME); - - if (matchesFile.exists()) - root.uploadFromImportDirectory(_dir.getName() + "/matches", "txt", null, true); - } - } - } - catch (IOException e) - { - // Fail the job in production mode, but succeed in dev mode. This allows us to test in an environment - // where Galaxy is not reachable. - if (!AppProps.getInstance().isDevMode()) - throw e; - - info("Could not connect to Galaxy server", e); - } - } - - - private synchronized boolean shouldUseGalaxy(@Nullable GalaxyServer server) - { - // First time through - if (null == _useGalaxy) - { - if (null == server) - { - // Galaxy is not configured, so don't use it - _useGalaxy = false; - } - else if (!AppProps.getInstance().isDevMode()) - { - // With a Galaxy configuration in production mode, always try to connect to Galaxy server (even if failures occur) - _useGalaxy = true; - } - else - { - // In dev mode, attempt a connection now and if it fails skip subsequent connections - _useGalaxy = server.canConnect(); - - if (!_useGalaxy) - warn("Test connect to Galaxy server failed"); - } - } - else - { - if (!_useGalaxy && null != server) // We already warned in the null case - warn("Skipping submit to Galaxy server due to previous connection failure"); - } - - return _useGalaxy; - } - - // Wait until analysis is completely prepared and has been submitted to Galaxy before monitoring - private void monitorCompletion() - { - if (null != _completionFile) - WorkflowCompletionMonitor.get().monitor(_completionFile); - } -} diff --git a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyFolderSettings.java b/genotyping/src/org/labkey/genotyping/galaxy/GalaxyFolderSettings.java deleted file mode 100644 index a4a9ee30..00000000 --- a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyFolderSettings.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010 LabKey Corporation - * - * 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. - */ -package org.labkey.genotyping.galaxy; - -/** - * User: adam - * Date: Sep 24, 2010 - * Time: 11:53:08 AM - */ -public interface GalaxyFolderSettings -{ - String getGalaxyURL(); -} diff --git a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyManager.java b/genotyping/src/org/labkey/genotyping/galaxy/GalaxyManager.java deleted file mode 100644 index 6936d006..00000000 --- a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyManager.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2010-2015 LabKey Corporation - * - * 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. - */ - -package org.labkey.genotyping.galaxy; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.labkey.api.data.Container; -import org.labkey.api.data.PropertyManager; -import org.labkey.api.data.PropertyManager.WritablePropertyMap; -import org.labkey.api.security.User; - -import java.util.Map; - -/** - * User: adam - * Date: Sep 24, 2010 - * Time: 11:56:14 AM - */ - -public class GalaxyManager -{ - private static final Logger LOG = LogManager.getLogger(GalaxyManager.class); - private static final GalaxyManager _instance = new GalaxyManager(); - - private GalaxyManager() - { - // prevent external construction with a private default constructor - } - - public static GalaxyManager get() - { - return _instance; - } - - private static final String FOLDER_CATEGORY = "GalaxySettings"; - private static final String GALAXY_URL = "GalaxyURL"; - - public void saveSettings(Container c, GalaxyFolderSettings settings) - { - WritablePropertyMap map = PropertyManager.getWritableProperties(c, FOLDER_CATEGORY, true); - map.put(GALAXY_URL, settings.getGalaxyURL()); - map.save(); - } - - public GalaxyFolderSettings getSettings(final Container c) - { - return new GalaxyFolderSettings() { - private final Map map = PropertyManager.getProperties(c, FOLDER_CATEGORY); - - @Override - public String getGalaxyURL() - { - return map.get(GALAXY_URL); - } - }; - } - - private static final String USER_CATEGORY = "GalaxyUserSettings"; - private static final String GALAXY_KEY = "GalaxyKey"; - - public void saveUserSettings(Container c, User user, GalaxyUserSettings userSettings) - { - WritablePropertyMap map = PropertyManager.getWritableProperties(user, c, USER_CATEGORY, true); - map.put(GALAXY_KEY, userSettings.getGalaxyKey()); - map.save(); - } - - public GalaxyUserSettings getUserSettings(final Container c, final User user) - { - return new GalaxyUserSettings() { - private final Map map = PropertyManager.getProperties(user, c, USER_CATEGORY); - - @Override - public String getGalaxyKey() - { - return map.get(GALAXY_KEY); - } - }; - } -} \ No newline at end of file diff --git a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyServer.java b/genotyping/src/org/labkey/genotyping/galaxy/GalaxyServer.java deleted file mode 100644 index deac1c3f..00000000 --- a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyServer.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (c) 2010-2015 LabKey Corporation - * - * 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. - */ -package org.labkey.genotyping.galaxy; - -import org.apache.hc.client5.http.classic.methods.HttpGet; -import org.apache.hc.client5.http.classic.methods.HttpPost; -import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; -import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; -import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; -import org.apache.hc.client5.http.impl.classic.HttpClientBuilder; -import org.apache.hc.core5.http.ContentType; -import org.apache.hc.core5.http.HttpEntity; -import org.apache.hc.core5.http.HttpStatus; -import org.apache.hc.core5.http.io.entity.StringEntity; -import org.apache.logging.log4j.LogManager; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.json.JSONArray; -import org.json.JSONObject; -import org.json.JSONStringer; -import org.json.JSONWriter; -import org.labkey.api.util.PageFlowUtil; -import org.labkey.api.util.URLHelper; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -/** - * User: adam - * Date: Aug 25, 2010 - * Time: 3:36:36 PM - */ - -// Provides ability to query and modify a Galaxy Server via the HTTP Galaxy API. All API calls require a Galaxy-generated -// web API key (see User -> Preferences -> Manage your information). -public class GalaxyServer -{ - private final String _serverUrl; - private final String _baseUrl; - private final String _key; - private final CloseableHttpClient _client; - - - public GalaxyServer(String serverUrl, String key) - { - _serverUrl = !serverUrl.endsWith("/") ? serverUrl : serverUrl.substring(0, serverUrl.length() - 1); - _baseUrl = _serverUrl + "/api/libraries"; - _key = key; - _client = HttpClientBuilder.create().build(); // Note: not thread-safe; assumes GalaxyServer is used in a single thread - } - - - public String getServerUrl() - { - return _serverUrl; - } - - - public List getDataLibraries() throws IOException - { - return getDataLibraries(get("")); - } - - - // Parse one or more libraries from a JSON array - private List getDataLibraries(String body) - { - JSONArray array = new JSONArray(body); - List list = new LinkedList<>(); - - for (int i = 0; i < array.length(); i++) - list.add(new DataLibrary((JSONObject)array.get(i))); - - return list; - } - - - private String get(String relativeUrl) throws IOException - { - return execute(new HttpGet(makeUrl(relativeUrl))); - } - - - private String execute(HttpUriRequestBase request) throws IOException - { - try (CloseableHttpResponse response = _client.execute(request)) - { - HttpEntity entity = response.getEntity(); - String contents = PageFlowUtil.getStreamContentsAsString(entity.getContent()); - - if (HttpStatus.SC_OK != response.getCode()) - throw new IOException("HTTP " + request.getMethod() + " Failed: " + response); - - return contents; - } - } - - - private String makeUrl(String relativeUrl) - { - return (relativeUrl.isEmpty() ? _baseUrl : _baseUrl + "/" + relativeUrl) + "?key=" + _key; - } - - - public boolean canConnect() - { - try - { - get(""); - return true; - } - catch (IOException e) - { - LogManager.getLogger(GalaxyServer.class).info("Test connect to Galaxy server failed", e); - return false; - } - } - - - public DataLibrary createLibrary(String name, @Nullable String description, @Nullable String synopsis) throws IOException - { - JSONWriter writer = new JSONStringer(); - writer.object(); - writer.key("name").value(name); - - if (null != description) - writer.key("description").value(description); - - if (null != synopsis) - writer.key("synopsis").value(synopsis); - - writer.endObject(); - - String response = post("", writer.toString()); - - List list = getDataLibraries(response); - - assert 1 == list.size(); - - return list.get(0); - } - - - private String post(String relativeUrl, String body) throws IOException - { - HttpPost post = new HttpPost(makeUrl(relativeUrl)); - post.setEntity(new StringEntity(body, ContentType.APPLICATION_JSON)); - post.setHeader("Content-Type", "application/json"); - - return execute(post); - } - - - public static class Item - { - private final ItemType _type; - private final String _apiUrl; - private final String _name; - private final String _id; - private final @Nullable Item _parent; - - private Item(@NotNull ItemType type, @Nullable Item parent, JSONObject json) - { - this(type, parent, json.getString("url"), json.getString("name"), json.getString("id")); - } - - private Item(@NotNull ItemType type, @Nullable Item parent, String apiUrl, String name, String id) - { - _type = type; - _parent = parent; - _apiUrl = apiUrl; - _name = name; - _id = id; - } - - public ItemType getType() - { - return _type; - } - - public @Nullable Item getParent() - { - return _parent; - } - - public String getApiUrl() - { - return _apiUrl; - } - - public String getName() - { - return _name; - } - - public String getId() - { - return _id; - } - } - - public class DataLibrary extends Item - { - private DataLibrary(JSONObject library) - { - super(ItemType.DataLibrary, null, library); - } - - public Folder getRootFolder() throws IOException - { - List children = getChildren(); - - for (LibraryItem child : children) - { - if (this.equals(child.getParent()) && "/".equals(child.getName())) - return (Folder)child; - } - - throw new IllegalStateException("No root folder found for data library " + getName()); - } - - public List getChildren() throws IOException - { - String body = get(getId() + "/contents"); - - JSONArray array = new JSONArray(body); - List list = new LinkedList<>(); - - for (int i = 0; i < array.length(); i++) - list.add(getLibraryItem(this, (JSONObject)array.get(i))); - - return list; - } - - public URLHelper getURL() throws URISyntaxException - { - return new URLHelper(getServerUrl() + "/library_common/browse_library?sort=name&f-description=All&f-name=All&cntrller=library&operation=browse").addParameter("id", getId()); - } - } - - public enum ItemType {DataLibrary, LibraryFolder, LibraryFile} - - private LibraryItem getLibraryItem(Item parent, JSONObject json) - { - String type = json.getString("type"); - - if ("folder".equals(type)) - return new Folder(parent, json); - else - return new File(parent, json); - } - - public abstract class LibraryItem extends Item - { - private LibraryItem(@NotNull ItemType type, @Nullable Item parent, JSONObject json) - { - super(type, parent, json); - } - - public Folder createFolder(String name, String description) throws IOException - { - JSONWriter writer = new JSONStringer(); - writer.object(); - writer.key("folder_id").value(getId()); - writer.key("name").value(name); - writer.key("create_type").value("folder"); - - if (null != description) - writer.key("description").value(description); - - writer.endObject(); - - String json = post(getId() + "/contents", writer.toString()); - JSONArray array = new JSONArray(json); - - return new Folder(this, (JSONObject)array.get(0)); - } - } - - public class Folder extends LibraryItem - { - private Folder(@Nullable Item parent, JSONObject json) - { - super(ItemType.LibraryFolder, parent, json); - } - - public List uploadFromImportDirectory(String serverPath, String fileType, @Nullable String dbKey, boolean linkData) throws IOException - { - JSONWriter writer = new JSONStringer(); - writer.object(); - writer.key("folder_id").value(getId()); - writer.key("server_dir").value(serverPath); - writer.key("file_type").value(fileType); - writer.key("dbkey").value(null != dbKey ? dbKey : "?"); - writer.key("upload_option").value("upload_directory"); - writer.key("create_type").value("file"); - writer.key("link_data_only").value(linkData ? "Yes" : "No"); - writer.endObject(); - - String json = post(getId() + "/contents", writer.toString()); - - // Parse one or more folders from a JSON array - JSONArray array = new JSONArray(json); - List list = new LinkedList<>(); - - for (int i = 0; i < array.length(); i++) - list.add(new File(this, (JSONObject)array.get(i))); - - return list; - } - } - - public class File extends LibraryItem - { - private File(@Nullable Item parent, JSONObject json) - { - super(ItemType.LibraryFile, parent, json); - } - - public Map getProperties() throws IOException - { - String body = get(getParent().getId() + "/contents/" + getId()); - return new JSONObject(body).toMap(); - } - } -} diff --git a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyUserSettings.java b/genotyping/src/org/labkey/genotyping/galaxy/GalaxyUserSettings.java deleted file mode 100644 index d0911783..00000000 --- a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyUserSettings.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010 LabKey Corporation - * - * 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. - */ -package org.labkey.genotyping.galaxy; - -/** - * User: adam - * Date: Sep 10, 2010 - * Time: 2:54:31 PM - */ -public interface GalaxyUserSettings -{ - String getGalaxyKey(); -} diff --git a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyUtils.java b/genotyping/src/org/labkey/genotyping/galaxy/GalaxyUtils.java deleted file mode 100644 index f9cdd41b..00000000 --- a/genotyping/src/org/labkey/genotyping/galaxy/GalaxyUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010-2012 LabKey Corporation - * - * 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. - */ -package org.labkey.genotyping.galaxy; - -import org.labkey.api.data.Container; -import org.labkey.api.security.User; -import org.labkey.api.security.permissions.AdminPermission; -import org.labkey.api.view.NotFoundException; - -/** - * User: adam - * Date: Oct 12, 2010 - * Time: 4:38:58 PM - */ - -// Provides a LabKey-specific way to create a GalaxyServer. This keeps GalaxyServer very generic and easier to publish. -public class GalaxyUtils -{ - // Throws NotFoundException if either galaxy URL (admin responsibility) or web API key (user responsibility) isn't configured. - public static GalaxyServer get(Container c, User user) - { - GalaxyFolderSettings settings = GalaxyManager.get().getSettings(c); - - if (null == settings.getGalaxyURL()) - { - String who = c.hasPermission(user, AdminPermission.class) ? "you" : "an administrator"; - throw new NotFoundException("To submit data to Galaxy, " + who + " must configure a Galaxy server URL via the genotyping admin page."); - } - - GalaxyUserSettings userSettings = GalaxyManager.get().getUserSettings(c, user); - - if (null == userSettings.getGalaxyKey()) - throw new NotFoundException("To submit data to Galaxy, you must first configure your Galaxy web API key using the \"my settings\" link"); - - return new GalaxyServer(settings.getGalaxyURL(), userSettings.getGalaxyKey()); - } -} diff --git a/genotyping/src/org/labkey/genotyping/galaxy/WorkflowCompletionMonitor.java b/genotyping/src/org/labkey/genotyping/galaxy/WorkflowCompletionMonitor.java deleted file mode 100644 index 0abbd0a3..00000000 --- a/genotyping/src/org/labkey/genotyping/galaxy/WorkflowCompletionMonitor.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2010-2016 LabKey Corporation - * - * 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. - */ -package org.labkey.genotyping.galaxy; - -import org.apache.logging.log4j.Logger; -import org.labkey.api.util.ContextListener; -import org.labkey.api.util.FileUtil; -import org.labkey.api.util.ShutdownListener; -import org.labkey.api.util.logging.LogHelper; -import org.labkey.genotyping.GenotypingManager; -import org.labkey.vfs.FileLike; - -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.net.http.HttpResponse.BodyHandler; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Properties; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -/** - * User: adam - * Date: Sep 28, 2010 - * Time: 9:41:02 PM - */ -public class WorkflowCompletionMonitor implements ShutdownListener -{ - private static final Logger LOG = LogHelper.getLogger(WorkflowCompletionMonitor.class, "Logger for Genotyping workflow completion monitor"); - private static final WorkflowCompletionMonitor INSTANCE = new WorkflowCompletionMonitor(); - - private final ScheduledExecutorService _executor = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "Genotyping Workflow Completion Monitor")); - private final List _pendingCompletionFiles = new CopyOnWriteArrayList<>(); - - - static - { - ContextListener.addShutdownListener(INSTANCE); - } - - - /* - This gets used only if a genotyping analysis gets submitted to Galaxy while the server is in dev mode. Most - configurations don't support an external Galaxy server pinging back to a developer's LabKey Server, so we signal - workflow completion via a file in the analysis directory. Steps: - - - SubmitAnalysisJob adds a "completeFilename" property to properties.xml - - SubmitAnalysisJob calls monitor() below cause WorkflowCompletionMonitor to watch for the specified file, checking - every 15 seconds for the existence of any pending files. - - When Galaxy workflow is complete, the workflow_complete task runs. If "completeFilename" is set in properties.xml - the task creates the specified file. - - The CheckForWorkflowCompletionsRunnable detects the file and signals the LabKey Server by invoking the same URL - the Galaxy workflow_complete task would have pinged; this provides a good test of the HTTP signaling mechanism. - */ - - public static WorkflowCompletionMonitor get() - { - return INSTANCE; - } - - - private WorkflowCompletionMonitor() - { - // Check for workflow complete files every 15 seconds - _executor.scheduleWithFixedDelay(new WorkflowCompletionMonitor.CheckForWorkflowCompletionsRunnable(), 15, 15, TimeUnit.SECONDS); - } - - - public void monitor(FileLike completionFile) - { - _pendingCompletionFiles.add(completionFile); - LOG.info("Monitoring for {}", FileUtil.getAbsolutePath(completionFile.toNioPathForRead())); - } - - - @Override - public String getName() - { - return "Genotyping workflow completion monitor"; - } - - @Override - public void shutdownStarted() - { - _executor.shutdown(); - } - - - private class CheckForWorkflowCompletionsRunnable implements Runnable - { - @Override - public void run() - { - int size = _pendingCompletionFiles.size(); - - if (size > 0) - { - LOG.info("Checking for completion of {} analys{}", size, 1 == size ? "is" : "es"); - - // TODO: with Java 21 this should be moved to an autoclosable - HttpClient client = HttpClient.newHttpClient(); - - for (FileLike file : _pendingCompletionFiles) - { - if (file.exists()) - { - try - { - // Load analysis properties - Properties props = GenotypingManager.get().readProperties(file.getParent()); - - // POST to the provided URL to signal LabKey Server that the workflow is complete - String url = (String) props.get("url"); - String analysisId = (String) props.get("analysis"); - LOG.info("Detected completion file for analysis {}; attempting to signal LabKey Server at {}", analysisId, url); - - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(url)) - .POST(HttpRequest.BodyPublishers.noBody()) - .build(); - BodyHandler bodyHandler = HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8); - HttpResponse response = client.send(request, bodyHandler); - String message = response.body(); - - LOG.info("LabKey response to analysis {} completion: \"{}\"", analysisId, message); - } - catch (Throwable t) - { - LOG.error("Exception while completing {}", file.toNioPathForRead().toAbsolutePath(), t); - } - finally - { - _pendingCompletionFiles.remove(file); - } - } - } - } - } - } -} diff --git a/genotyping/src/org/labkey/genotyping/view/analyze.jsp b/genotyping/src/org/labkey/genotyping/view/analyze.jsp deleted file mode 100644 index 0bc9e449..00000000 --- a/genotyping/src/org/labkey/genotyping/view/analyze.jsp +++ /dev/null @@ -1,195 +0,0 @@ -<% -/* - * Copyright (c) 2010-2016 LabKey Corporation - * - * 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. - */ -%> -<%@ page import="org.labkey.api.query.CustomView" %> -<%@ page import="org.labkey.api.util.Pair" %> -<%@ page import="org.labkey.api.view.template.ClientDependencies" %> -<%@ page import="org.labkey.genotyping.GenotypingController" %> -<%@ page import="org.labkey.genotyping.GenotypingController.AnalyzeBean" %> -<%@ page import="java.io.IOException" %> -<%@ page import="java.util.Map" %> -<%@ page import="java.util.SortedSet" %> -<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<%! - @Override - public void addClientDependencies(ClientDependencies dependencies) - { - dependencies.add("clientapi/ext3"); - } -%> -<% - AnalyzeBean bean = (AnalyzeBean)getModelBean(); - -// ext-all.css hard-codes a white background, we want transparent instead %> - - -
- - diff --git a/genotyping/src/org/labkey/genotyping/view/configure.jsp b/genotyping/src/org/labkey/genotyping/view/configure.jsp index 8b002b7c..8cffe2e2 100644 --- a/genotyping/src/org/labkey/genotyping/view/configure.jsp +++ b/genotyping/src/org/labkey/genotyping/view/configure.jsp @@ -116,9 +116,6 @@ <%=h(form.getMessage())%>   <% } %> - Configure Galaxy - Galaxy server home page URL -   Configure Genotyping Queries External source of DNA reference sequences   diff --git a/genotyping/src/org/labkey/genotyping/view/importReads.jsp b/genotyping/src/org/labkey/genotyping/view/importReads.jsp index 66ec423d..9be3bdea 100644 --- a/genotyping/src/org/labkey/genotyping/view/importReads.jsp +++ b/genotyping/src/org/labkey/genotyping/view/importReads.jsp @@ -71,7 +71,6 @@ - <%= button("Import Reads").submit(true) %> <%=platform == SEQUENCE_PLATFORMS.LS454 ? button("Import Reads And Analyze").submit(true).onClick("document.importReads.analyze.value=1;") : HtmlString.EMPTY_STRING%> diff --git a/genotyping/src/org/labkey/genotyping/view/mySettings.jsp b/genotyping/src/org/labkey/genotyping/view/mySettings.jsp deleted file mode 100644 index c54465f9..00000000 --- a/genotyping/src/org/labkey/genotyping/view/mySettings.jsp +++ /dev/null @@ -1,53 +0,0 @@ -<% -/* - * Copyright (c) 2010-2014 LabKey Corporation - * - * 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. - */ -%> -<%@ page import="org.labkey.api.util.URLHelper"%> -<%@ page import="org.labkey.genotyping.GenotypingController" %> -<%@ page import="org.labkey.genotyping.GenotypingController.MySettingsAction" %> -<%@ page import="org.labkey.genotyping.galaxy.GalaxyFolderSettings" %> -<%@ page import="org.labkey.genotyping.galaxy.GalaxyManager" %> -<%@ taglib prefix="labkey" uri="http://www.labkey.org/taglib" %> -<%@ page extends="org.labkey.api.jsp.JspBase" %> -<% - GenotypingController.MySettingsForm form = (GenotypingController.MySettingsForm)getModelBean(); - GalaxyFolderSettings settings = GalaxyManager.get().getSettings(getContainer()); - String serverURL = settings.getGalaxyURL(); - String preferencesHTML = "the API Keys page"; - - // Make it a link if admin has set the Galaxy URL - if (null != serverURL) - { - URLHelper userURL = new URLHelper((serverURL.endsWith("/") ? serverURL : serverURL + "/") + "user/api_keys"); - preferencesHTML = "" + preferencesHTML + ""; - } -%> - - - <%=formatMissedErrorsInTable("form", 2)%> - - - - - - -
- You need to provide a Galaxy web API key to send data from LabKey to your Galaxy server. Galaxy generates a - unique web API key for each user and uses it to authorize every call to the Galaxy web API. You can find or - generate a key by logging into Galaxy and visiting <%=unsafe(preferencesHTML)%>. Copy the 32-character hexadecimal - string and paste it in the box below. -
 
Galaxy web API key
 
<%= button("Submit").submit(true) %> <%= button("Cancel").href(form.getReturnUrlHelper()) %><%=generateReturnUrlFormField(form)%>
-
diff --git a/genotyping/src/org/labkey/genotyping/view/overview.jsp b/genotyping/src/org/labkey/genotyping/view/overview.jsp index d9fec53a..ec3c4fae 100644 --- a/genotyping/src/org/labkey/genotyping/view/overview.jsp +++ b/genotyping/src/org/labkey/genotyping/view/overview.jsp @@ -99,8 +99,7 @@ Settings - - <%=link("My Settings", GenotypingController.getMySettingsURL(c, getActionURL()))%><% + <% if (c.hasPermission(user, AdminPermission.class)) { %> diff --git a/genotyping/test/src/org/labkey/test/tests/GenotypingBaseTest.java b/genotyping/test/src/org/labkey/test/tests/GenotypingBaseTest.java index 61e065b4..815f3c2f 100644 --- a/genotyping/test/src/org/labkey/test/tests/GenotypingBaseTest.java +++ b/genotyping/test/src/org/labkey/test/tests/GenotypingBaseTest.java @@ -90,17 +90,11 @@ protected void configureAdmin(boolean configureSequences) _extHelper.waitForExt3MaskToDisappear(WAIT_FOR_JAVASCRIPT); } } + clickButton("Submit"); if (configureSequences) { - setFormElement(Locator.name("galaxyURL"), "http://galaxy.labkey.org:8080"); - clickButton("Submit"); clickButton("Load Sequences"); - - log("Configure Galaxy Server Key"); - clickAndWait(Locator.linkWithText("My Settings")); - setFormElement(Locator.name("galaxyKey"), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } - clickButton("Submit"); } @Override diff --git a/genotyping/test/src/org/labkey/test/tests/GenotypingTest.java b/genotyping/test/src/org/labkey/test/tests/GenotypingTest.java index 32d6c074..f7d3e09c 100644 --- a/genotyping/test/src/org/labkey/test/tests/GenotypingTest.java +++ b/genotyping/test/src/org/labkey/test/tests/GenotypingTest.java @@ -25,8 +25,6 @@ import org.labkey.test.categories.OConnor; import org.openqa.selenium.NoSuchElementException; -import java.io.File; - @Category({CustomModules.class, OConnor.class}) @BaseWebDriverTest.ClassTimeout(minutes = 9) public class GenotypingTest extends GenotypingBaseTest @@ -34,8 +32,6 @@ public class GenotypingTest extends GenotypingBaseTest public static final String first454importNum = "207"; public static final String second454importNum = "208"; - protected int runNum = 0; //this is globally unique, so we need to retrieve it every time. - @Override protected String getProjectName() { @@ -65,9 +61,7 @@ public void testSteps() { //TODO: need to fix 454/genotyping tests importRunTest(); - runAnalysisTest(); importSecondRunTest(); - verifyAnalysis(); } private void importSecondRunTest() @@ -95,65 +89,6 @@ private void importRunAgainTest() } } - private void runAnalysisTest() - { - sendDataToGalaxyServer(); - receiveDataFromGalaxyServer(); - } - - private void verifyAnalysis() - { - goToProjectHome(); - - clickAndWait(Locator.linkWithText("View Analyses")); - clickAndWait(Locator.linkWithText("" + getRunNumber())); // TODO: This is probably still too permissive... need a more specific way to get the run link - - assertTextPresent("Reads", "Sample Id", "Percent", "TEST09"); - assertElementPresent(Locator.paginationText(1, 100, 1410)); - } - - private void receiveDataFromGalaxyServer() - { - String[] filesToCopy = {"matches.txt", "analysis_complete.txt"}; - String analysisFolder = "analysis_" + getRunNumber(); - for (String file: filesToCopy) - { - copyFile(new File(getPipelineLoc(), file), new File(getPipelineLoc(), analysisFolder + "/" + file)); - } - refresh(); - waitForPipelineJobsToComplete(++pipelineJobCount, "Import genotyping analysis", false); - } - - private int getRunNumber() - { - return runNum; - } - - private void sendDataToGalaxyServer() - { - clickButton("Add Analysis"); - _extHelper.selectComboBoxItem("Reference Sequences:", "[default]"); //TODO: this should be cyno - clickButton("Submit"); - waitForPipelineJobsToComplete(++pipelineJobCount, "Submit genotyping analysis", false); - findAndSetAnalysisNumber(); - - } - - private void findAndSetAnalysisNumber() - { - Locator l = Locator.tagContainingText("td", "Submit genotyping analysis"); - isElementPresent(l); - getText(l); - String[] temp = getText(l).split(" "); - setAnalysisNumber(Integer.parseInt(temp[temp.length-1])); - - } - - private void setAnalysisNumber(int i) - { - runNum = i; - } - private void importRunTest() { log("import genotyping run"); @@ -183,6 +118,5 @@ private void startImportRun(String file, String importAction, String associatedR _fileBrowserHelper.importFile(file, importAction); selectOptionByText(Locator.name("run"), associatedRun); clickButton("Import Reads"); - } }