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
5 changes: 4 additions & 1 deletion api/src/org/labkey/api/attachments/AttachmentService.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ static AttachmentService get()

HttpView<?> getFindAttachmentParentsView();

void logOrphanedAttachments();
/**
* Logs the first 20 orphaned attachments it detects. Returns the total number of orphaned attachments detected.
*/
int logOrphanedAttachments();

void deleteOrphanedAttachments();

Expand Down
4 changes: 3 additions & 1 deletion api/src/org/labkey/api/data/ContainerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1944,7 +1944,9 @@ private static boolean delete(final Container c, User user, @Nullable String com
setContainerTabDeleted(c.getParent(), c.getName(), c.getParent().getFolderType().getName());
}

AttachmentService.get().logOrphanedAttachments();
// Log orphaned attachments in this server, but only in dev mode, since this is for our testing
if (AppProps.getInstance().isDevMode())
AttachmentService.get().logOrphanedAttachments();

fireDeleteContainer(c, user);

Expand Down
14 changes: 14 additions & 0 deletions core/src/org/labkey/core/admin/AdminController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3710,6 +3710,20 @@ public void addNavTrail(NavTree root)
}
}

@AdminConsoleAction
public static class LogOrphanedAttachmentsAction extends ReadOnlyApiAction<Object>
{
@Override
public Object execute(Object o, BindException errors) throws Exception
{
int count = 0;
AttachmentService svc = AttachmentService.get();
if (svc != null)
count = svc.logOrphanedAttachments();
return Map.of("count", count);
}
}

public static ActionURL getMemTrackerURL(boolean clearCaches, boolean gc)
{
ActionURL url = new ActionURL(MemTrackerAction.class, ContainerManager.getRoot());
Expand Down
11 changes: 7 additions & 4 deletions core/src/org/labkey/core/attachment/AttachmentServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1101,10 +1101,10 @@ public int available()
private record Orphan(String documentName, String parentType){}

@Override
public void logOrphanedAttachments()
public int logOrphanedAttachments()
{
// Log orphaned attachments in this server, but in dev mode only, since this is for our testing. Also, we
// don't yet offer a way to delete orphaned attachments via the UI, so it's not helpful to inform admins.
int ret = 0;

if (AppProps.getInstance().isDevMode())
{
User user = ElevatedUser.getElevatedUser(User.getSearchUser(), TroubleshooterRole.class);
Expand All @@ -1118,7 +1118,8 @@ public void logOrphanedAttachments()
List<Orphan> orphans = new TableSelector(documents, new CsvSet("DocumentName, ParentType"), filter, null).getArrayList(Orphan.class);
if (!orphans.isEmpty())
{
LOG.error("Found {}, which likely indicates a problem with a delete method or a container listener.", StringUtilsLabKey.pluralize(orphans.size(), "orphaned attachment"));
ret = orphans.size();
LOG.error("Found {}, which likely indicates a problem with a delete method or a container listener.", StringUtilsLabKey.pluralize(ret, "orphaned attachment"));

final String message;
if (orphans.size() > MAX_ORPHANS_TO_LOG)
Expand All @@ -1136,6 +1137,8 @@ public void logOrphanedAttachments()
}
}
}

return ret;
}

record OrphanedAttachment(String container, String parent, String parentType, String documentName)
Expand Down
Loading