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

DataBiosphere / consent / #5684

17 Apr 2025 07:36PM UTC coverage: 79.057% (+0.02%) from 79.034%
#5684

push

web-flow
DT-1537: Ensure that study info is populated when indexing dataset terms (#2483)

12 of 14 new or added lines in 5 files covered. (85.71%)

2 existing lines in 2 files now uncovered.

10264 of 12983 relevant lines covered (79.06%)

0.79 hits per line

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

84.26
/src/main/java/org/broadinstitute/consent/http/resources/DatasetResource.java
1
package org.broadinstitute.consent.http.resources;
2

3
import com.codahale.metrics.annotation.Timed;
4
import com.google.api.client.http.HttpStatusCodes;
5
import com.google.gson.Gson;
6
import com.google.gson.JsonSyntaxException;
7
import com.google.inject.Inject;
8
import com.networknt.schema.ValidationMessage;
9
import io.dropwizard.auth.Auth;
10
import jakarta.annotation.security.PermitAll;
11
import jakarta.annotation.security.RolesAllowed;
12
import jakarta.ws.rs.BadRequestException;
13
import jakarta.ws.rs.Consumes;
14
import jakarta.ws.rs.DELETE;
15
import jakarta.ws.rs.ForbiddenException;
16
import jakarta.ws.rs.GET;
17
import jakarta.ws.rs.NotFoundException;
18
import jakarta.ws.rs.PATCH;
19
import jakarta.ws.rs.POST;
20
import jakarta.ws.rs.PUT;
21
import jakarta.ws.rs.Path;
22
import jakarta.ws.rs.PathParam;
23
import jakarta.ws.rs.Produces;
24
import jakarta.ws.rs.QueryParam;
25
import jakarta.ws.rs.core.Context;
26
import jakarta.ws.rs.core.MediaType;
27
import jakarta.ws.rs.core.Response;
28
import jakarta.ws.rs.core.StreamingOutput;
29
import jakarta.ws.rs.core.UriBuilder;
30
import jakarta.ws.rs.core.UriInfo;
31
import java.net.URI;
32
import java.util.ArrayList;
33
import java.util.List;
34
import java.util.Map;
35
import java.util.Objects;
36
import java.util.Set;
37
import java.util.function.Predicate;
38
import java.util.stream.Collectors;
39
import org.broadinstitute.consent.http.enumeration.UserRoles;
40
import org.broadinstitute.consent.http.models.AuthUser;
41
import org.broadinstitute.consent.http.models.DataUse;
42
import org.broadinstitute.consent.http.models.Dataset;
43
import org.broadinstitute.consent.http.models.DatasetPatch;
44
import org.broadinstitute.consent.http.models.DatasetStudySummary;
45
import org.broadinstitute.consent.http.models.DatasetSummary;
46
import org.broadinstitute.consent.http.models.DatasetUpdate;
47
import org.broadinstitute.consent.http.models.Study;
48
import org.broadinstitute.consent.http.models.User;
49
import org.broadinstitute.consent.http.models.UserRole;
50
import org.broadinstitute.consent.http.models.dataset_registration_v1.DatasetRegistrationSchemaV1;
51
import org.broadinstitute.consent.http.models.dataset_registration_v1.builder.DatasetRegistrationSchemaV1Builder;
52
import org.broadinstitute.consent.http.service.DatasetRegistrationService;
53
import org.broadinstitute.consent.http.service.DatasetService;
54
import org.broadinstitute.consent.http.service.ElasticSearchService;
55
import org.broadinstitute.consent.http.service.UserService;
56
import org.broadinstitute.consent.http.util.JsonSchemaUtil;
57
import org.broadinstitute.consent.http.util.gson.GsonUtil;
58
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
59
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
60
import org.glassfish.jersey.media.multipart.FormDataParam;
61

62

63
@Path("api/dataset")
64
public class DatasetResource extends Resource {
65

66
  private final DatasetService datasetService;
67
  private final DatasetRegistrationService datasetRegistrationService;
68
  private final UserService userService;
69
  private final ElasticSearchService elasticSearchService;
70

71
  private final JsonSchemaUtil jsonSchemaUtil;
72

73
  @Inject
74
  public DatasetResource(DatasetService datasetService, UserService userService,
75
      DatasetRegistrationService datasetRegistrationService,
76
      ElasticSearchService elasticSearchService) {
1✔
77
    this.datasetService = datasetService;
1✔
78
    this.userService = userService;
1✔
79
    this.datasetRegistrationService = datasetRegistrationService;
1✔
80
    this.elasticSearchService = elasticSearchService;
1✔
81
    this.jsonSchemaUtil = new JsonSchemaUtil();
1✔
82
  }
1✔
83

84
  @POST
85
  @Consumes({MediaType.MULTIPART_FORM_DATA})
86
  @Produces({MediaType.APPLICATION_JSON})
87
  @Path("/v3")
88
  @RolesAllowed({ADMIN, CHAIRPERSON, DATASUBMITTER})
89
  /*
90
   * This endpoint accepts a json instance of a dataset-registration-schema_v1.json schema.
91
   * With that object, we can fully create datasets from the provided values.
92
   */
93
  public Response createDatasetRegistration(
94
      @Auth AuthUser authUser,
95
      FormDataMultiPart multipart,
96
      @FormDataParam("dataset") String json) {
97
    try {
98
      Set<ValidationMessage> errors = jsonSchemaUtil.validateSchema_v1(json);
1✔
99
      if (!errors.isEmpty()) {
1✔
100
        throw new BadRequestException(
1✔
101
            "Invalid schema:\n"
102
                + String.join("\n", errors.stream().map(ValidationMessage::getMessage).toList()));
1✔
103
      }
104

105
      DatasetRegistrationSchemaV1 registration = jsonSchemaUtil.deserializeDatasetRegistration(
1✔
106
          json);
107
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
108

109
      // key: field name (not file name), value: file body part
110
      Map<String, FormDataBodyPart> files = extractFilesFromMultiPart(multipart);
1✔
111

112
      // Generate datasets from registration
113
      List<Dataset> datasets = datasetRegistrationService.createDatasetsFromRegistration(
1✔
114
          registration,
115
          user,
116
          files);
117
      Study study = datasets.get(0).getStudy();
1✔
118
      DatasetRegistrationSchemaV1Builder builder = new DatasetRegistrationSchemaV1Builder();
1✔
119
      DatasetRegistrationSchemaV1 createdRegistration = builder.build(study, datasets);
1✔
120
      URI uri = UriBuilder.fromPath(String.format("/api/dataset/study/%s", study.getStudyId()))
1✔
121
          .build();
1✔
122
      String entity = GsonUtil.buildGsonNullSerializer().toJson(createdRegistration);
1✔
123
      return Response.created(uri).entity(entity).build();
1✔
124
    } catch (Exception e) {
1✔
125
      return createExceptionResponse(e);
1✔
126
    }
127
  }
128

129
  /**
130
   * This endpoint updates the dataset.
131
   */
132
  @PUT
133
  @Consumes({MediaType.MULTIPART_FORM_DATA})
134
  @Produces({MediaType.APPLICATION_JSON})
135
  @Path("/v3/{datasetId}")
136
  @RolesAllowed({ADMIN, CHAIRPERSON})
137
  public Response updateByDatasetUpdate(
138
      @Auth AuthUser authUser,
139
      @PathParam("datasetId") Integer datasetId,
140
      FormDataMultiPart multipart,
141
      @FormDataParam("dataset") String json) {
142

143
    try {
144
      if (json == null || json.isEmpty()) {
1✔
145
        throw new BadRequestException("Dataset is required");
1✔
146
      }
147
      DatasetUpdate update = new DatasetUpdate(json);
1✔
148

149
      Dataset datasetExists = datasetService.findDatasetById(datasetId);
1✔
150
      if (Objects.isNull(datasetExists)) {
1✔
151
        throw new NotFoundException("Could not find the dataset with id: " + datasetId);
1✔
152
      }
153

154
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
155

156
      // key: field name (not file name), value: file body part
157
      Map<String, FormDataBodyPart> files = extractFilesFromMultiPart(multipart);
1✔
158

159
      Dataset updatedDataset = datasetRegistrationService.updateDataset(datasetId, user, update,
1✔
160
          files);
161
      return Response.ok().entity(updatedDataset).build();
1✔
162
    } catch (Exception e) {
1✔
163
      return createExceptionResponse(e);
1✔
164
    }
165
  }
166

167
  /**
168
   * This endpoint updates the dataset.
169
   */
170
  @PATCH
171
  @Consumes({MediaType.APPLICATION_JSON})
172
  @Produces({MediaType.APPLICATION_JSON})
173
  @Path("/{datasetId}")
174
  @RolesAllowed({ADMIN, CHAIRPERSON, DATASUBMITTER})
175
  public Response patchByDatasetUpdate(@Auth AuthUser authUser,
176
      @PathParam("datasetId") Integer datasetId, String json) {
177
    try {
178
      Dataset existingDataset = datasetService.findDatasetById(datasetId);
1✔
179
      if (existingDataset == null) {
1✔
180
        throw new NotFoundException("Could not find the dataset with id: " + datasetId);
1✔
181
      }
182
      // Check permissions for non-admin roles.
183
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
184
      if (!user.hasUserRole(UserRoles.ADMIN)) {
1✔
185
        if (!existingDataset.isCreator(user) && !existingDataset.isCustodian(user)) {
1✔
186
          throw new ForbiddenException("User does not have permission to update this dataset");
1✔
187
        }
188
      }
189
      if (json == null || json.isEmpty()) {
1✔
190
        throw new BadRequestException("Dataset Patch is required");
1✔
191
      }
192
      Gson gson = GsonUtil.getInstance();
1✔
193
      DatasetPatch patch;
194
      try {
195
        patch = gson.fromJson(json, DatasetPatch.class);
1✔
196
      } catch (Exception e) {
1✔
197
        throw new BadRequestException("Unable to parse dataset patch: " + json);
1✔
198
      }
1✔
199
      if (!patch.isPatchable(existingDataset)) {
1✔
200
        return Response.notModified().entity(existingDataset).build();
1✔
201
      }
202
      // Validate DatasetPatch values
203
      List<String> existingNames = datasetService.findAllDatasetNames();
1✔
204
      if (patch.name() != null && !patch.name().equals(existingDataset.getName())
1✔
205
          && existingNames.contains(patch.name())) {
1✔
206
        throw new BadRequestException("The new name for this dataset already exists: " + patch.name());
1✔
207
      }
208
      if (!patch.validateProperties()) {
1✔
209
        throw new BadRequestException("Properties are invalid");
1✔
210
      }
211
      Dataset patched = datasetRegistrationService.patchDataset(datasetId, user, patch);
1✔
212
      elasticSearchService.synchronizeDatasetInESIndex(patched, user, false);
1✔
213
      return Response.ok(patched).build();
1✔
214
    } catch (Exception e) {
1✔
215
      return createExceptionResponse(e);
1✔
216
    }
217
  }
218

219
  @GET
220
  @Produces("application/json")
221
  @PermitAll
222
  @Path("/v2")
223
  public Response findAllDatasetsStreaming(@Auth AuthUser authUser) {
224
    try {
225
      userService.findUserByEmail(authUser.getEmail());
1✔
226
      StreamingOutput streamedDatasets = datasetService.findAllDatasetsAsStreamingOutput();
1✔
227
      return Response.ok().entity(streamedDatasets).build();
1✔
228
    } catch (Exception e) {
×
229
      return createExceptionResponse(e);
×
230
    }
231
  }
232

233
  @GET
234
  @Produces("application/json")
235
  @PermitAll
236
  @Path("/v3")
237
  public Response findAllDatasetStudySummaries(@Auth AuthUser authUser) {
238
    try {
239
      userService.findUserByEmail(authUser.getEmail());
1✔
240
      List<DatasetStudySummary> summaries = datasetService.findAllDatasetStudySummaries();
1✔
241
      return Response.ok(summaries).build();
1✔
242
    } catch (Exception e) {
×
243
      return createExceptionResponse(e);
×
244
    }
245
  }
246

247
  @GET
248
  @Path("/v2/{datasetId}")
249
  @Produces("application/json")
250
  @PermitAll
251
  public Response getDataset(@PathParam("datasetId") Integer datasetId) {
252
    try {
253
      Dataset dataset = datasetService.findDatasetById(datasetId);
1✔
254
      if (Objects.isNull(dataset)) {
1✔
255
        throw new NotFoundException("Could not find the dataset with id: " + datasetId.toString());
1✔
256
      }
257
      return Response.ok(dataset).build();
1✔
258
    } catch (Exception e) {
1✔
259
      return createExceptionResponse(e);
1✔
260
    }
261
  }
262

263
  @GET
264
  @Path("/registration/{datasetIdentifier}")
265
  @Produces(MediaType.APPLICATION_JSON)
266
  @PermitAll
267
  public Response getRegistrationFromDatasetIdentifier(@Auth AuthUser authUser,
268
      @PathParam("datasetIdentifier") String datasetIdentifier) {
269
    try {
270
      Dataset dataset = datasetService.findDatasetByIdentifier(datasetIdentifier);
1✔
271
      if (Objects.isNull(dataset)) {
1✔
272
        throw new NotFoundException(
1✔
273
            "No dataset exists for dataset identifier: " + datasetIdentifier);
274
      }
275
      Study study;
276
      if (dataset.getStudy() != null && dataset.getStudy().getStudyId() != null) {
1✔
277
        study = datasetService.findStudyById(dataset.getStudy().getStudyId());
1✔
278
      } else {
279
        throw new NotFoundException("No study exists for dataset identifier: " + datasetIdentifier);
×
280
      }
281
      DatasetRegistrationSchemaV1 registration = new DatasetRegistrationSchemaV1Builder().build(
1✔
282
          study, List.of(dataset));
1✔
283
      String entity = GsonUtil.buildGsonNullSerializer().toJson(registration);
1✔
284
      return Response.ok().entity(entity).build();
1✔
285
    } catch (Exception e) {
1✔
286
      return createExceptionResponse(e);
1✔
287
    }
288
  }
289

290
  @GET
291
  @Path("/batch")
292
  @Produces("application/json")
293
  @PermitAll
294
  public Response getDatasets(@QueryParam("ids") List<Integer> datasetIds) {
295
    try {
296
      List<Dataset> datasets = datasetService.findDatasetsByIds(datasetIds);
1✔
297

298
      Set<Integer> foundIds = datasets.stream().map(Dataset::getDatasetId)
1✔
299
          .collect(Collectors.toSet());
1✔
300
      if (!foundIds.containsAll(datasetIds)) {
1✔
301
        // find the differences
302
        List<Integer> differences = new ArrayList<>(datasetIds)
1✔
303
            .stream()
1✔
304
            .filter(Objects::nonNull)
1✔
305
            .filter(Predicate.not(foundIds::contains))
1✔
306
            .toList();
1✔
307
        throw new NotFoundException(
1✔
308
            "Could not find datasets with ids: "
309
                + String.join(",",
1✔
310
                differences.stream().map(Object::toString).collect(Collectors.toSet())));
1✔
311

312
      }
313
      return Response.ok(datasets).build();
1✔
314
    } catch (Exception e) {
1✔
315
      return createExceptionResponse(e);
1✔
316
    }
317
  }
318

319
  @GET
320
  @Consumes("application/json")
321
  @Produces("application/json")
322
  @Path("/validate")
323
  @PermitAll
324
  public Response validateDatasetName(@QueryParam("name") String name) {
325
    try {
326
      Dataset datasetWithName = datasetService.getDatasetByName(name);
1✔
327
      return Response.ok().entity(datasetWithName.getDatasetId()).build();
1✔
328
    } catch (Exception e) {
1✔
329
      throw new NotFoundException("Could not find the dataset with name: " + name);
1✔
330
    }
331
  }
332

333
  @GET
334
  @Consumes("application/json")
335
  @Produces("application/json")
336
  @Path("/studyNames")
337
  @PermitAll
338
  public Response findAllStudyNames() {
339
    try {
340
      Set<String> studyNames = datasetService.findAllStudyNames();
1✔
341
      return Response.ok(studyNames).build();
1✔
342
    } catch (Exception e) {
1✔
343
      return createExceptionResponse(e);
1✔
344
    }
345
  }
346

347
  @GET
348
  @Consumes("application/json")
349
  @Produces("application/json")
350
  @Path("/datasetNames")
351
  @PermitAll
352
  public Response findAllDatasetNames() {
353
    try {
354
      List<String> datasetNames = datasetService.findAllDatasetNames();
×
355
      return Response.ok(datasetNames).build();
×
356
    } catch (Exception e) {
×
357
      return createExceptionResponse(e);
×
358
    }
359
  }
360

361
  @DELETE
362
  @Produces(MediaType.APPLICATION_JSON)
363
  @Path("/{datasetId}")
364
  @RolesAllowed({ADMIN, CHAIRPERSON, DATASUBMITTER})
365
  public Response delete(@Auth AuthUser authUser, @PathParam("datasetId") Integer datasetId,
366
      @Context UriInfo info) {
367
    try {
368
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
369
      Dataset dataset = datasetService.findDatasetById(datasetId);
1✔
370
      if (Objects.nonNull(dataset.getDeletable()) && !dataset.getDeletable()) {
1✔
371
        throw new BadRequestException("Dataset is in use and cannot be deleted.");
×
372
      }
373
      // Validate that the admin/chairperson/data submitter has edit/delete access to this dataset
374
      validateDatasetDacAccess(user, dataset);
1✔
375
      try {
376
        datasetService.deleteDataset(datasetId, user.getUserId());
1✔
377
      } catch (Exception e) {
×
378
        logException(e);
×
379
        return createExceptionResponse(e);
×
380
      }
1✔
381
      try (var deleteResponse = elasticSearchService.deleteIndex(datasetId, user.getUserId())) {
1✔
382
        if (!HttpStatusCodes.isSuccess(deleteResponse.getStatus())) {
1✔
383
          logWarn("Unable to delete index for dataset: " + datasetId);
1✔
384
        }
385
      }
386
      return Response.ok().build();
1✔
387
    } catch (Exception e) {
1✔
388
      return createExceptionResponse(e);
1✔
389
    }
390
  }
391

392
  @POST
393
  @Path("/index")
394
  @RolesAllowed(ADMIN)
395
  public Response indexDatasets(@Auth AuthUser authUser) {
396
    try {
397
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
398
      var datasetIds = datasetService.findAllDatasetIds();
1✔
399
      StreamingOutput indexResponse = elasticSearchService.indexDatasetIds(datasetIds, user);
1✔
400
      return Response.ok(indexResponse, MediaType.APPLICATION_JSON).build();
1✔
401
    } catch (Exception e) {
×
402
      return createExceptionResponse(e);
×
403
    }
404
  }
405

406
  @POST
407
  @Path("/index/{datasetId}")
408
  @RolesAllowed(ADMIN)
409
  public Response indexDataset(@Auth AuthUser authUser, @PathParam("datasetId") Integer datasetId) {
410
    try {
411
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
412
      return elasticSearchService.indexDataset(datasetId, user);
1✔
UNCOV
413
    } catch (Exception e) {
×
414
      return createExceptionResponse(e);
×
415
    }
416
  }
417

418
  @DELETE
419
  @Path("/index/{datasetId}")
420
  @RolesAllowed(ADMIN)
421
  public Response deleteDatasetIndex(@Auth AuthUser authUser, @PathParam("datasetId") Integer datasetId) {
422
    try {
423
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
424
      return elasticSearchService.deleteIndex(datasetId, user.getUserId());
1✔
425
    } catch (Exception e) {
×
426
      return createExceptionResponse(e);
×
427
    }
428
  }
429

430
  @GET
431
  @Produces("application/json")
432
  @Path("/autocomplete")
433
  @PermitAll
434
  @Timed
435
  public Response autocompleteDatasets(
436
      @Auth AuthUser authUser,
437
      @QueryParam("query") String query) {
438
    try {
439
      userService.findUserByEmail(authUser.getEmail());
1✔
440
      List<DatasetSummary> datasets = datasetService.searchDatasetSummaries(query);
1✔
441
      return Response.ok(datasets).build();
1✔
442
    } catch (Exception e) {
×
443
      return createExceptionResponse(e);
×
444
    }
445
  }
446

447
  @POST
448
  @Path("/search/index")
449
  @Consumes("application/json")
450
  @Produces("application/json")
451
  @PermitAll
452
  @Timed
453
  public Response searchDatasetIndex(@Auth AuthUser authUser, String query) {
454
    try {
455
      userService.findUserByEmail(authUser.getEmail());
1✔
456
      return elasticSearchService.searchDatasets(query);
1✔
457
    } catch (Exception e) {
×
458
      return createExceptionResponse(e);
×
459
    }
460
  }
461

462
  @PUT
463
  @Produces("application/json")
464
  @RolesAllowed(ADMIN)
465
  @Path("/{id}/datause")
466
  public Response updateDatasetDataUse(@Auth AuthUser authUser, @PathParam("id") Integer id,
467
      String dataUseJson) {
468
    try {
469
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
470
      Gson gson = new Gson();
1✔
471
      DataUse dataUse = gson.fromJson(dataUseJson, DataUse.class);
1✔
472
      Dataset originalDataset = datasetService.findDatasetById(id);
1✔
473
      if (Objects.isNull(originalDataset)) {
1✔
474
        throw new NotFoundException("Dataset not found: " + id);
×
475
      }
476
      if (Objects.equals(dataUse, originalDataset.getDataUse())) {
1✔
477
        return Response.notModified().entity(originalDataset).build();
1✔
478
      }
479
      Dataset dataset = datasetService.updateDatasetDataUse(user, id, dataUse);
1✔
480
      return Response.ok().entity(dataset).build();
1✔
481
    } catch (JsonSyntaxException jse) {
1✔
482
      return createExceptionResponse(
1✔
483
          new BadRequestException("Invalid JSON Syntax: " + dataUseJson));
484
    } catch (Exception e) {
1✔
485
      return createExceptionResponse(e);
1✔
486
    }
487
  }
488

489
  @PUT
490
  @Produces("application/json")
491
  @RolesAllowed(ADMIN)
492
  @Path("/{id}/reprocess/datause")
493
  public Response syncDataUseTranslation(@Auth AuthUser authUser, @PathParam("id") Integer id) {
494
    try {
495
      User user = userService.findUserByEmail(authUser.getEmail());
1✔
496
      Dataset ds = datasetService.syncDatasetDataUseTranslation(id, user);
1✔
497
      return Response.ok(ds).build();
1✔
498
    } catch (Exception e) {
1✔
499
      return createExceptionResponse(e);
1✔
500
    }
501
  }
502

503
  private void validateDatasetDacAccess(User user, Dataset dataset) {
504
    if (user.hasUserRole(UserRoles.ADMIN)) {
1✔
505
      return;
1✔
506
    }
507
    if (user.hasUserRole(UserRoles.DATASUBMITTER)) {
1✔
508
      if (dataset.getCreateUserId().equals(user.getUserId())) {
×
509
        return;
×
510
      }
511
      // If the user doesn't have any other appropriate role, we can return an error here,
512
      // otherwise, continue checking if the user has chair permissions
513
      if (!user.hasUserRole(UserRoles.CHAIRPERSON)) {
×
514
        logWarn("User does not have permission to delete dataset: " + user.getEmail());
×
515
        throw new NotFoundException();
×
516
      }
517
    }
518
    List<Integer> dacIds = user.getRoles().stream()
1✔
519
        .filter(r -> r.getRoleId().equals(UserRoles.CHAIRPERSON.getRoleId()))
1✔
520
        .map(UserRole::getDacId)
1✔
521
        .toList();
1✔
522
    if (dacIds.isEmpty()) {
1✔
523
      // Something went very wrong here. A chairperson with no dac ids is an error
524
      logWarn("Unable to find dac ids for chairperson user: " + user.getEmail());
×
525
      throw new NotFoundException();
×
526
    } else {
527
      if (Objects.isNull(dataset) || Objects.isNull(dataset.getDacId())) {
1✔
528
        logWarn("Cannot find a valid dac id for dataset: " + dataset.getDatasetId());
1✔
529
        throw new NotFoundException();
1✔
530
      } else {
531
        if (!dacIds.contains(dataset.getDacId())) {
1✔
532
          throw new NotFoundException();
1✔
533
        }
534
      }
535
    }
536
  }
1✔
537

538
}
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

© 2026 Coveralls, Inc