Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 3 additions & 36 deletions api/src/org/labkey/api/action/BaseApiAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.jetbrains.annotations.NotNull;
import org.labkey.api.miniprofiler.MiniProfiler;
import org.labkey.api.miniprofiler.Timing;
import org.labkey.api.query.BatchValidationException;
Expand All @@ -37,7 +39,6 @@
import org.labkey.api.util.HttpUtil;
import org.labkey.api.util.JsonUtil;
import org.labkey.api.util.MimeMap;
import org.labkey.api.util.ResponseHelper;
import org.labkey.api.util.StringUtilsLabKey;
import org.labkey.api.view.BadRequestException;
import org.labkey.api.view.NotFoundException;
Expand All @@ -50,13 +51,10 @@
import org.springframework.validation.Errors;
import org.springframework.web.servlet.ModelAndView;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.SocketTimeoutException;
import java.time.Duration;
import java.util.Map;

/**
Expand Down Expand Up @@ -201,37 +199,6 @@ public ModelAndView handlePost() throws Exception
}
else
{
boolean cachable = false;

// ETag header
String eTag = getETag(form);
if (eTag != null)
{
getViewContext().getResponse().setHeader("ETag", eTag);
cachable = true;
}

// Last-Modified header
long lastModified = getLastModified(form);
if (lastModified != Long.MIN_VALUE)
{
getViewContext().getResponse().addDateHeader("Last-Modified", lastModified);
cachable = true;
}

if (cachable)
{
// Include max-age to tell the browser to cache for a short duration before making another request to check "If-Modified-Since"
ResponseHelper.setPrivate(getViewContext().getResponse(), Duration.ofSeconds(10));
}

// Check if the conditions specified in the optional If headers are satisfied.
if (!ResponseHelper.checkIfHeaders(getViewContext(), eTag, lastModified))
{
assert getViewContext().getResponse().getStatus() != HttpServletResponse.SC_OK;
return null;
}

Object response;
try (Timing ignored = MiniProfiler.step("execute"))
{
Expand Down
16 changes: 0 additions & 16 deletions api/src/org/labkey/api/action/BaseViewAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -770,20 +770,4 @@ public String getCommandName()
{
return _commandName;
}

/**
* Cacheable resources can calculate a last modified timestamp to send to the browser.
*/
protected long getLastModified(FORM form)
{
return Long.MIN_VALUE;
}

/**
* Cacheable resources can calculate an ETag header to send to the browser.
*/
protected String getETag(FORM form)
{
return null;
}
}
2 changes: 0 additions & 2 deletions api/src/org/labkey/api/data/DbScope.java
Original file line number Diff line number Diff line change
Expand Up @@ -1624,7 +1624,6 @@ public void invalidateSchema(DbSchema schema)
*/
public void invalidateSchema(String schemaName, DbSchemaType type)
{
QueryService.get().updateLastModified();
_schemaCache.remove(schemaName, type);
invalidateAllTables(schemaName, type);
}
Expand All @@ -1641,7 +1640,6 @@ private void invalidateAllTables(String schemaName, DbSchemaType type)
// DbSchema.
public void invalidateTable(String schemaName, String tableName, DbSchemaType type)
{
QueryService.get().updateLastModified();
getTableInfoCache(type).remove(schemaName, tableName, type);
_schemaCache.remove(schemaName, type);
}
Expand Down
7 changes: 0 additions & 7 deletions api/src/org/labkey/api/query/QueryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@

public interface QueryService
{
String EXPERIMENTAL_LAST_MODIFIED = "queryMetadataLastModified";
String EXPERIMENTAL_DISABLE_MANAGED_TRIGGER_COLUMNS = "queryDisableManagedTriggerColumns";
String EXPERIMENTAL_PRODUCT_ALL_FOLDER_LOOKUPS = "queryProductAllFolderLookups";
String EXPERIMENTAL_PRODUCT_PROJECT_DATA_LISTING_SCOPED = "queryProductProjectDataListingScoped";
Expand Down Expand Up @@ -135,12 +134,6 @@ static void setInstance(QueryService impl)

// TODO: These probably need to change to support data source qualified schema names

/** Get the value used for the "Last-Modified" time stamp in query metadata API responses. */
long metadataLastModified();

/** Invalidate the value used for the "Last-Modified" time stamp. */
void updateLastModified();

/** Get schema for SchemaKey encoded path. */
UserSchema getUserSchema(User user, Container container, String schemaPath);
/** Get schema for SchemaKey path. */
Expand Down
20 changes: 2 additions & 18 deletions api/src/org/labkey/api/util/ResponseHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@

// place to centralize some common usages

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jetbrains.annotations.NotNull;
import org.labkey.api.view.ViewContext;
import org.springframework.http.ContentDisposition;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
Expand Down Expand Up @@ -166,21 +165,6 @@ public static void setContentDisposition(HttpServletResponse response, ContentDi
response.setHeader("Content-Disposition", type.toHeaderValue(filename));
}


/**
* Check if the conditions specified in the optional If headers are
* satisfied.
*
* @return boolean true if the resource meets all the specified conditions,
* and false if any of the conditions is not satisfied, in which case
* request processing is stopped
*/
public static boolean checkIfHeaders(ViewContext context, String eTag, long lastModified)
throws IOException
{
return checkIfHeaders(context.getRequest(), context.getResponse(), eTag, lastModified);
}

/**
* Check if the conditions specified in the optional If headers are
* satisfied.
Expand Down
1 change: 0 additions & 1 deletion assay/src/org/labkey/assay/AssayDomainServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,6 @@ public GWTProtocol saveChanges(GWTProtocol assay, boolean replaceIfExisting) thr
QueryService.get().saveCalculatedFieldsMetadata(domainDescriptor.getSchemaName(), domainDescriptor.getQueryName(), null, domain.getCalculatedFields(), hasExistingCalcFields, getUser(), protocol.getContainer());
}

QueryService.get().updateLastModified();
transaction.commit();
AssayManager.get().clearProtocolCache();
return getAssayDefinition(assay.getProtocolId(), false);
Expand Down
2 changes: 0 additions & 2 deletions assay/src/org/labkey/assay/ModuleAssayCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.labkey.api.module.ModuleResourceCaches;
import org.labkey.api.module.ResourceRootProvider;
import org.labkey.api.pipeline.PipelineProvider;
import org.labkey.api.query.QueryService;
import org.labkey.api.util.Path;

import java.util.Collection;
Expand Down Expand Up @@ -72,7 +71,6 @@ void clearModuleAssayCollections()
synchronized (PROVIDER_LOCK)
{
_moduleAssayCollections = null;
QueryService.get().updateLastModified();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -922,8 +922,6 @@ else if (!isDomainNew)
getDomainKind().invalidate(this);
};
transaction.addCommitTask(afterDomainCommitOrRollback, DbScope.CommitTaskOption.POSTCOMMIT, DbScope.CommitTaskOption.POSTROLLBACK);

QueryService.get().updateLastModified();
transaction.commit();
}
}
Expand Down
4 changes: 0 additions & 4 deletions query/src/org/labkey/query/QueryModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,6 @@ public QuerySchema createSchema(DefaultSchema schema, Module module)
DataViewService.get().registerProvider(QueryDataViewProvider.TYPE, new QueryDataViewProvider());
DataViewService.get().registerProvider(InheritedQueryDataViewProvider.TYPE, new InheritedQueryDataViewProvider());

OptionalFeatureService.get().addExperimentalFeatureFlag(QueryServiceImpl.EXPERIMENTAL_LAST_MODIFIED, "Include Last-Modified header on query metadata requests",
"For schema, query, and view metadata requests include a Last-Modified header such that the browser can cache the response. " +
"The metadata is invalidated when performing actions such as creating a new List or modifying the columns on a custom view", false);
OptionalFeatureService.get().addExperimentalFeatureFlag(USE_ROW_BY_ROW_UPDATE, "Use row-by-row update",
"For Query.updateRows api, do row-by-row update, instead of using a prepared statement that updates rows in batches.", false);
OptionalFeatureService.get().addExperimentalFeatureFlag(QueryServiceImpl.EXPERIMENTAL_PRODUCT_ALL_FOLDER_LOOKUPS, "Less restrictive product folder lookups",
Expand Down Expand Up @@ -308,7 +305,6 @@ public void doStartup(ModuleContext moduleContext)
// Note: DailyMessageDigest timer is initialized by the AnnouncementModule

CacheManager.addListener(new ServerManager.CacheListener());
CacheManager.addListener(new QueryServiceImpl.CacheListener());

AdminLinkManager.getInstance().addListener((adminNavTree, container, user) -> {
if (container.hasPermission(user, ReadPermission.class))
Expand Down
81 changes: 0 additions & 81 deletions query/src/org/labkey/query/QueryServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@
import org.labkey.api.module.ModuleLoader;
import org.labkey.api.module.ModuleResourceCache;
import org.labkey.api.module.ModuleResourceCacheHandler;
import org.labkey.api.module.ModuleResourceCacheListener;
import org.labkey.api.module.ModuleResourceCaches;
import org.labkey.api.module.ResourceRootProvider;
import org.labkey.api.pipeline.PipelineJob;
Expand Down Expand Up @@ -191,7 +190,6 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
Expand All @@ -207,7 +205,6 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
Expand Down Expand Up @@ -235,46 +232,11 @@ public void fillResourceRoots(@NotNull Resource topRoot, @NotNull Collection<Res
private static final ModuleResourceCache<MultiValuedMap<Path, ModuleQueryDef>> MODULE_QUERY_DEF_CACHE = ModuleResourceCaches.create("Module query definitions", new QueryDefResourceCacheHandler(), QUERY_AND_ASSAY_PROVIDER);
private static final ModuleResourceCache<MultiValuedMap<Path, ModuleQueryMetadataDef>> MODULE_QUERY_METADATA_DEF_CACHE = ModuleResourceCaches.create("Module query meta data", new QueryMetaDataDefResourceCacheHandler(), QUERY_AND_ASSAY_PROVIDER);
private static final ModuleResourceCache<MultiValuedMap<Path, ModuleCustomViewDef>> MODULE_CUSTOM_VIEW_CACHE = ModuleResourceCaches.create("Module custom view definitions", new CustomViewResourceCacheHandler(), QUERY_AND_ASSAY_PROVIDER);

private static final ModuleResourceCacheListener INVALIDATE_QUERY_METADATA_HANDLER = new ModuleResourceCacheListener()
{
@Override
public void entryCreated(java.nio.file.Path directory, java.nio.file.Path entry)
{
QueryService.get().updateLastModified();
}

@Override
public void entryDeleted(java.nio.file.Path directory, java.nio.file.Path entry)
{
QueryService.get().updateLastModified();
}

@Override
public void entryModified(java.nio.file.Path directory, java.nio.file.Path entry)
{
QueryService.get().updateLastModified();
}

@Override
public void overflow()
{
}

@Override
public void moduleChanged(Module module)
{
QueryService.get().updateLastModified();
}
};

private final ConcurrentMap<Class<? extends Controller>, Pair<Module, String>> _schemaLinkActions = new ConcurrentHashMap<>();
private QueryAnalysisService _queryAnalysisService;

private final List<QueryIconURLProvider> _queryIconURLProviders = new CopyOnWriteArrayList<>();

private final AtomicLong _metadataLastModified = new AtomicLong(new Date().getTime());

private final List<CompareType> COMPARE_TYPES = new CopyOnWriteArrayList<>(Arrays.asList(
CompareType.EQUAL,
CompareType.DATE_EQUAL,
Expand Down Expand Up @@ -696,30 +658,6 @@ static public QueryServiceImpl get()
return (QueryServiceImpl) QueryService.get();
}

static class CacheListener implements org.labkey.api.cache.CacheListener
{
@Override
public void clearCaches()
{
QueryServiceImpl.get().updateLastModified();
}
}

/** Get the value used for the "Last-Modified" time stamp in query metadata API responses. */
@Override
public long metadataLastModified()
{
return AppProps.getInstance().isOptionalFeatureEnabled(EXPERIMENTAL_LAST_MODIFIED) ?
_metadataLastModified.get() : Long.MIN_VALUE;
}

/** Invalidate the value used for the "Last-Modified" time stamp. */
@Override
public void updateLastModified()
{
_metadataLastModified.set(new Date().getTime());
}

@Override
public UserSchema getUserSchema(User user, Container container, String schemaPath)
{
Expand Down Expand Up @@ -984,7 +922,6 @@ public void uncacheModuleResources(Module module)
MODULE_QUERY_DEF_CACHE.onModuleChanged(module);
MODULE_QUERY_METADATA_DEF_CACHE.onModuleChanged(module);
MODULE_CUSTOM_VIEW_CACHE.onModuleChanged(module);
INVALIDATE_QUERY_METADATA_HANDLER.moduleChanged(module);
}

private static class QueryDefResourceCacheHandler implements ModuleResourceCacheHandler<MultiValuedMap<Path, ModuleQueryDef>>
Expand All @@ -997,12 +934,6 @@ public MultiValuedMap<Path, ModuleQueryDef> load(Stream<? extends Resource> reso
.map(resource -> new ModuleQueryDef(module, resource))
.collect(LabKeyCollectors.toMultiValuedMap(def -> def.getPath().getParent(), def -> def)));
}

@Override
public @Nullable ModuleResourceCacheListener createChainedListener(Module module)
{
return INVALIDATE_QUERY_METADATA_HANDLER;
}
}

@Override
Expand Down Expand Up @@ -1434,12 +1365,6 @@ public MultiValuedMap<Path, ModuleCustomViewDef> load(Stream<? extends Resource>
.map(ModuleCustomViewDef::new)
.collect(LabKeyCollectors.toMultiValuedMap(def -> def.getPath().getParent(), def -> def)));
}

@Override
public @Nullable ModuleResourceCacheListener createChainedListener(Module module)
{
return INVALIDATE_QUERY_METADATA_HANDLER;
}
}

@Override
Expand Down Expand Up @@ -2555,12 +2480,6 @@ public MultiValuedMap<Path, ModuleQueryMetadataDef> load(Stream<? extends Resour
.map(ModuleQueryMetadataDef::new)
.collect(LabKeyCollectors.toMultiValuedMap(def -> def.getPath().getParent(), def -> def)));
}

@Override
public @Nullable ModuleResourceCacheListener createChainedListener(Module module)
{
return INVALIDATE_QUERY_METADATA_HANDLER;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,6 @@ public class GetQueryDetailsAction extends ReadOnlyApiAction<GetQueryDetailsActi
{
private static final Logger LOG = LogManager.getLogger(GetQueryDetailsAction.class);

@Override
protected long getLastModified(Form form)
{
return QueryService.get().metadataLastModified();
}

@Override
public ApiResponse execute(Form form, BindException errors)
{
Expand Down
Loading