• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IQSS / dataverse / #22693

03 Jul 2024 01:09PM CUT coverage: 20.626% (-0.09%) from 20.716%
#22693

push

github

web-flow
Merge pull request #10664 from IQSS/develop

merge develop into master for 6.3

195 of 1852 new or added lines in 82 files covered. (10.53%)

72 existing lines in 33 files now uncovered.

17335 of 84043 relevant lines covered (20.63%)

0.21 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/DestroyDatasetCommand.java
1
package edu.harvard.iq.dataverse.engine.command.impl;
2

3
import edu.harvard.iq.dataverse.DataFile;
4
import edu.harvard.iq.dataverse.Dataset;
5
import edu.harvard.iq.dataverse.DatasetVersion;
6
import edu.harvard.iq.dataverse.Dataverse;
7
import edu.harvard.iq.dataverse.GlobalId;
8
import edu.harvard.iq.dataverse.authorization.DataverseRole;
9
import edu.harvard.iq.dataverse.search.IndexServiceBean;
10
import edu.harvard.iq.dataverse.RoleAssignment;
11
import edu.harvard.iq.dataverse.authorization.Permission;
12
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
13
import static edu.harvard.iq.dataverse.dataset.DatasetUtil.deleteDatasetLogo;
14
import edu.harvard.iq.dataverse.engine.command.AbstractVoidCommand;
15
import edu.harvard.iq.dataverse.engine.command.CommandContext;
16
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
17
import edu.harvard.iq.dataverse.engine.command.RequiredPermissions;
18
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
19
import edu.harvard.iq.dataverse.engine.command.exception.PermissionException;
20
import edu.harvard.iq.dataverse.pidproviders.PidProvider;
21
import edu.harvard.iq.dataverse.pidproviders.PidUtil;
22
import edu.harvard.iq.dataverse.search.IndexResponse;
23
import java.util.ArrayList;
24
import java.util.Collections;
25
import java.util.Iterator;
26
import java.util.List;
27
import java.util.logging.Level;
28
import java.util.logging.Logger;
29

30
import edu.harvard.iq.dataverse.batch.util.LoggingUtil;
31
import java.io.IOException;
32
import java.util.concurrent.Future;
33
import org.apache.solr.client.solrj.SolrServerException;
34

35
/**
36
 * Same as {@link DeleteDatasetCommand}, but does not stop if the dataset is
37
 * published. This command is reserved for super-users, if at all.
38
 *
39
 * @author michael
40
 */
41
// Since this is used by DeleteDatasetCommand, must have at least that permission
42
// (for released, user is checked for superuser)
43
@RequiredPermissions( Permission.DeleteDatasetDraft )
44
public class DestroyDatasetCommand extends AbstractVoidCommand {
45

46
    private static final Logger logger = Logger.getLogger(DestroyDatasetCommand.class.getCanonicalName());
×
47

48
    private final Dataset doomed;
49
    
50
    private List<String> datasetAndFileSolrIdsToDelete; 
51
    
52
    private Dataverse toReIndex;
53

54
    public DestroyDatasetCommand(Dataset doomed, DataverseRequest aRequest) {
55
        super(aRequest, doomed);
×
56
        this.doomed = doomed;
×
57
        datasetAndFileSolrIdsToDelete = new ArrayList<>();
×
58
    }
×
59

60
    @Override
61
    protected void executeImpl(CommandContext ctxt) throws CommandException {
62

63
        // first check if dataset is released, and if so, if user is a superuser
64
        if ( doomed.isReleased() && (!(getUser() instanceof AuthenticatedUser) || !getUser().isSuperuser() ) ) {      
×
65
            throw new PermissionException("Destroy can only be called by superusers.",
×
66
                this,  Collections.singleton(Permission.DeleteDatasetDraft), doomed);                
×
67
        }
NEW
68
        Dataset managedDoomed = ctxt.em().merge(doomed);
×
69
        
70
        // If there is a dedicated thumbnail DataFile, it needs to be reset
71
        // explicitly, or we'll get a constraint violation when deleting:
NEW
72
        managedDoomed.setThumbnailFile(null);
×
73

74
        // files need to iterate through and remove 'by hand' to avoid
75
        // optimistic lock issues... (plus the physical files need to be 
76
        // deleted too!)
NEW
77
        DatasetVersion dv = managedDoomed.getLatestVersion();
×
NEW
78
        Iterator <DataFile> dfIt = managedDoomed.getFiles().iterator();
×
79
        while (dfIt.hasNext()){
×
80
            DataFile df = dfIt.next();
×
81
            // Gather potential Solr IDs of files. As of this writing deaccessioned files are never indexed.
82
            String solrIdOfPublishedFile = IndexServiceBean.solrDocIdentifierFile + df.getId();
×
83
            datasetAndFileSolrIdsToDelete.add(solrIdOfPublishedFile);
×
84
            String solrIdOfDraftFile = IndexServiceBean.solrDocIdentifierFile + df.getId() + IndexServiceBean.draftSuffix;
×
85
            datasetAndFileSolrIdsToDelete.add(solrIdOfDraftFile);
×
86
            ctxt.engine().submit(new DeleteDataFileCommand(df, getRequest(), true));
×
87
            dfIt.remove();
×
88
        }
×
NEW
89
        dv.setFileMetadatas(null);
×
90
        
91
        
92
        // ASSIGNMENTS
NEW
93
        for (RoleAssignment ra : ctxt.roles().directRoleAssignments(managedDoomed)) {
×
94
            ctxt.em().remove(ra);
×
95
        }
×
96
        // ROLES
NEW
97
        for (DataverseRole ra : ctxt.roles().findByOwnerId(managedDoomed.getId())) {
×
98
            ctxt.em().remove(ra);
×
99
        }   
×
100
        
NEW
101
        if (!managedDoomed.isHarvested()) {
×
102
            //also, lets delete the uploaded thumbnails!
NEW
103
            deleteDatasetLogo(managedDoomed);
×
104
            // and remove the PID (perhaps should be after the remove in case that causes a roll-back?)
NEW
105
            GlobalId pid = managedDoomed.getGlobalId();
×
106
            if (pid != null) {
×
107
                PidProvider pidProvider = PidUtil.getPidProvider(pid.getProviderId());
×
108
                try {
NEW
109
                    if (pidProvider.alreadyRegistered(managedDoomed)) {
×
NEW
110
                        pidProvider.deleteIdentifier(managedDoomed);
×
111
                        //Files are handled in DeleteDataFileCommand
112
                    }
113
                } catch (Exception e) {
×
114
                    logger.log(Level.WARNING, "Identifier deletion was not successful:", e.getMessage());
×
115
                }
×
116
            }
117
        }
118
        
119
        toReIndex = managedDoomed.getOwner();
×
120

121
        // add potential Solr IDs of datasets to list for deletion
NEW
122
        String solrIdOfPublishedDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + managedDoomed.getId();
×
123
        datasetAndFileSolrIdsToDelete.add(solrIdOfPublishedDatasetVersion);
×
NEW
124
        String solrIdOfDraftDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + managedDoomed.getId() + IndexServiceBean.draftSuffix;
×
125
        datasetAndFileSolrIdsToDelete.add(solrIdOfDraftDatasetVersion);
×
126
        String solrIdOfDraftDatasetVersionPermission = solrIdOfDraftDatasetVersion + IndexServiceBean.discoverabilityPermissionSuffix;
×
127
        datasetAndFileSolrIdsToDelete.add(solrIdOfDraftDatasetVersionPermission);
×
NEW
128
        String solrIdOfDeaccessionedDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + managedDoomed.getId() + IndexServiceBean.deaccessionedSuffix;
×
129
        datasetAndFileSolrIdsToDelete.add(solrIdOfDeaccessionedDatasetVersion);
×
130
        
131
        // dataset
NEW
132
        ctxt.em().remove(managedDoomed);
×
133

134

UNCOV
135
    }
×
136

137
    @Override 
138
    public boolean onSuccess(CommandContext ctxt, Object r) {
139

140
        boolean retVal = true;
×
141
        
142
       // all the real Solr work is done here
143
       // delete orphaned Solr ids
144
        IndexResponse resultOfSolrDeletionAttempt = ctxt.solrIndex().deleteMultipleSolrIds(datasetAndFileSolrIdsToDelete);
×
145
        logger.log(Level.FINE, "Result of attempt to delete dataset and file IDs from the search index: {0}", resultOfSolrDeletionAttempt.getMessage());
×
146

147
        // reindex
148
        try {
149
            ctxt.index().indexDataverse(toReIndex);                   
×
150
        } catch (IOException | SolrServerException e) {    
×
151
            String failureLogText = "Post-destroy dataset indexing of the owning dataverse failed. You can kickoff a re-index of this dataverse with: \r\n curl http://localhost:8080/api/admin/index/dataverses/" + toReIndex.getId().toString();
×
152
            failureLogText += "\r\n" + e.getLocalizedMessage();
×
153
            LoggingUtil.writeOnSuccessFailureLog(this, failureLogText,  toReIndex);
×
154
            retVal = false;
×
155
        }
×
156
        
157
        return retVal;
×
158
    }
159

160
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc