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

IQSS / dataverse / #22002

01 Apr 2024 07:56PM CUT coverage: 20.716% (+0.5%) from 20.173%
#22002

push

github

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

Merge 6.2 into master

704 of 2679 new or added lines in 152 files covered. (26.28%)

81 existing lines in 49 files now uncovered.

17160 of 82836 relevant lines covered (20.72%)

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

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

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

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

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

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

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

62
        // first check if dataset is released, and if so, if user is a superuser
63
        if ( doomed.isReleased() && (!(getUser() instanceof AuthenticatedUser) || !getUser().isSuperuser() ) ) {      
×
64
            throw new PermissionException("Destroy can only be called by superusers.",
×
65
                this,  Collections.singleton(Permission.DeleteDatasetDraft), doomed);                
×
66
        }
67
        
68
        // If there is a dedicated thumbnail DataFile, it needs to be reset
69
        // explicitly, or we'll get a constraint violation when deleting:
70
        doomed.setThumbnailFile(null);
×
71
        final Dataset managedDoomed = ctxt.em().merge(doomed);
×
72
        
73
        // files need to iterate through and remove 'by hand' to avoid
74
        // optimistic lock issues... (plus the physical files need to be 
75
        // deleted too!)
76
        
77
        Iterator <DataFile> dfIt = doomed.getFiles().iterator();
×
78
        while (dfIt.hasNext()){
×
79
            DataFile df = dfIt.next();
×
80
            // Gather potential Solr IDs of files. As of this writing deaccessioned files are never indexed.
81
            String solrIdOfPublishedFile = IndexServiceBean.solrDocIdentifierFile + df.getId();
×
82
            datasetAndFileSolrIdsToDelete.add(solrIdOfPublishedFile);
×
83
            String solrIdOfDraftFile = IndexServiceBean.solrDocIdentifierFile + df.getId() + IndexServiceBean.draftSuffix;
×
84
            datasetAndFileSolrIdsToDelete.add(solrIdOfDraftFile);
×
85
            ctxt.engine().submit(new DeleteDataFileCommand(df, getRequest(), true));
×
86
            dfIt.remove();
×
87
        }
×
88
        
89
        //also, lets delete the uploaded thumbnails!
90
        if (!doomed.isHarvested()) {
×
91
            deleteDatasetLogo(doomed);
×
92
        }
93
        
94
        
95
        // ASSIGNMENTS
96
        for (RoleAssignment ra : ctxt.roles().directRoleAssignments(doomed)) {
×
97
            ctxt.em().remove(ra);
×
98
        }
×
99
        // ROLES
100
        for (DataverseRole ra : ctxt.roles().findByOwnerId(doomed.getId())) {
×
101
            ctxt.em().remove(ra);
×
102
        }   
×
103
        
104
        if (!doomed.isHarvested()) {
×
NEW
105
            GlobalId pid = doomed.getGlobalId();
×
NEW
106
            if (pid != null) {
×
NEW
107
                PidProvider pidProvider = PidUtil.getPidProvider(pid.getProviderId());
×
108
                try {
NEW
109
                    if (pidProvider.alreadyRegistered(doomed)) {
×
NEW
110
                        pidProvider.deleteIdentifier(doomed);
×
NEW
111
                        for (DataFile df : doomed.getFiles()) {
×
NEW
112
                            pidProvider.deleteIdentifier(df);
×
NEW
113
                        }
×
114
                    }
NEW
115
                } catch (Exception e) {
×
NEW
116
                    logger.log(Level.WARNING, "Identifier deletion was not successful:", e.getMessage());
×
117
                }
×
118
            }
119
        }
120
        
121
        toReIndex = managedDoomed.getOwner();
×
122

123
        // dataset
124
        ctxt.em().remove(managedDoomed);
×
125

126
        // add potential Solr IDs of datasets to list for deletion
127
        String solrIdOfPublishedDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + doomed.getId();
×
128
        datasetAndFileSolrIdsToDelete.add(solrIdOfPublishedDatasetVersion);
×
129
        String solrIdOfDraftDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + doomed.getId() + IndexServiceBean.draftSuffix;
×
130
        datasetAndFileSolrIdsToDelete.add(solrIdOfDraftDatasetVersion);
×
131
        String solrIdOfDraftDatasetVersionPermission = solrIdOfDraftDatasetVersion + IndexServiceBean.discoverabilityPermissionSuffix;
×
132
        datasetAndFileSolrIdsToDelete.add(solrIdOfDraftDatasetVersionPermission);
×
133
        String solrIdOfDeaccessionedDatasetVersion = IndexServiceBean.solrDocIdentifierDataset + doomed.getId() + IndexServiceBean.deaccessionedSuffix;
×
134
        datasetAndFileSolrIdsToDelete.add(solrIdOfDeaccessionedDatasetVersion);
×
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