Skip to content

Commit d293d8b

Browse files
committed
Concept Set Snapshots/Locking/Unlocking feature implementation
1 parent 27d8b5a commit d293d8b

24 files changed

+947
-9
lines changed

src/main/java/org/ohdsi/webapi/security/model/ConceptSetPermissionSchema.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class ConceptSetPermissionSchema extends EntityPermissionSchema {
1515
put("conceptset:%s:annotation:*:delete", "Delete Annotations of Concept Set with ID = %s");
1616
put("conceptset:*:annotation:*:delete", "Delete Annotations of any Concept Set");
1717
put("conceptset:%s:delete", "Delete Concept Set with ID = %s");
18+
put("conceptset:%s:snapshot:post", "Invoke Snapshot Action for Concept Set with ID = %s");
1819
}};
1920

2021
private static Map<String, String> readPermissions = new HashMap<String, String>() {{

src/main/java/org/ohdsi/webapi/service/AbstractDaoService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,4 +489,9 @@ protected <T extends CommonEntityDTO> List<T> listByTags(List<? extends CommonEn
489489
})
490490
.collect(Collectors.toList());
491491
}
492+
493+
public TagService getTagService() {
494+
return tagService;
495+
}
496+
492497
}

src/main/java/org/ohdsi/webapi/service/ConceptSetService.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.io.ByteArrayOutputStream;
1919
import java.util.*;
20+
import java.util.function.Supplier;
2021
import java.util.stream.Collectors;
2122
import java.util.stream.StreamSupport;
2223

@@ -47,9 +48,17 @@
4748
import org.ohdsi.webapi.service.annotations.SearchDataTransformer;
4849
import org.ohdsi.webapi.service.dto.AnnotationDetailsDTO;
4950
import org.ohdsi.webapi.service.dto.ConceptSetDTO;
51+
import org.ohdsi.webapi.service.dto.LockedConceptSetsResponse;
5052
import org.ohdsi.webapi.service.dto.SaveConceptSetAnnotationsRequest;
5153
import org.ohdsi.webapi.service.dto.AnnotationDTO;
5254
import org.ohdsi.webapi.service.dto.CopyAnnotationsRequest;
55+
import org.ohdsi.webapi.service.lock.ConceptSetLockingService;
56+
import org.ohdsi.webapi.service.lock.dto.ConceptSetSnapshotActionRequest;
57+
import org.ohdsi.webapi.service.lock.dto.ConceptSetSnapshotParameters;
58+
import org.ohdsi.webapi.service.lock.dto.GetConceptSetSnapshotItemsRequest;
59+
import org.ohdsi.webapi.service.lock.dto.GetConceptSetSnapshotItemsResponse;
60+
import org.ohdsi.webapi.service.lock.dto.IsLockedBatchCheckRequest;
61+
import org.ohdsi.webapi.service.lock.dto.IsLockedBatchCheckResponse;
5362
import org.ohdsi.webapi.shiro.Entities.UserEntity;
5463
import org.ohdsi.webapi.shiro.Entities.UserRepository;
5564
import org.ohdsi.webapi.shiro.management.Security;
@@ -145,6 +154,8 @@ public void customize(CacheManager cacheManager) {
145154
@Autowired
146155
private ObjectMapper mapper;
147156

157+
@Autowired
158+
private ConceptSetLockingService conceptSetLockingService;
148159

149160
@Value("${security.defaultGlobalReadPermissions}")
150161
private boolean defaultGlobalReadPermissions;
@@ -191,6 +202,19 @@ public Collection<ConceptSetDTO> getConceptSets() {
191202

192203
}
193204

205+
/**
206+
* Get the list of concept sets that were locked using the snapshot lock feature
207+
*
208+
* @summary Get all locked concept sets
209+
* @return A list of locked concept sets
210+
*/
211+
@GET
212+
@Path("/locked")
213+
@Produces(MediaType.APPLICATION_JSON)
214+
public Collection<LockedConceptSetsResponse> getLockedConceptSets() {
215+
return conceptSetLockingService.getLockedConceptSets(defaultGlobalReadPermissions);
216+
}
217+
194218
/**
195219
* Get the concept set items for a selected concept set ID.
196220
*
@@ -564,6 +588,71 @@ public ConceptSetDTO updateConceptSet(@PathParam("id") final int id, ConceptSetD
564588
ConceptSet conceptSet = conversionService.convert(conceptSetDTO, ConceptSet.class);
565589
return conversionService.convert(updateConceptSet(updated, conceptSet), ConceptSetDTO.class);
566590
}
591+
@Path("/{id}/snapshots")
592+
@GET
593+
@Produces(MediaType.APPLICATION_JSON)
594+
public List<ConceptSetSnapshotParameters> listSnapshots(@PathParam("id") final int id) throws Exception {
595+
return conceptSetLockingService.listSnapshotsByConceptSetId(id);
596+
}
597+
598+
@Path("/{id}/snapshot")
599+
@GET
600+
@Produces(MediaType.APPLICATION_JSON)
601+
public ConceptSetSnapshotParameters getLastSnapshot(@PathParam("id") final int id) throws Exception {
602+
return conceptSetLockingService.getLastSnapshotByConceptSetId(id);
603+
}
604+
605+
@POST
606+
@Path("/{id}/snapshot")
607+
@Consumes(MediaType.APPLICATION_JSON)
608+
@Produces(MediaType.APPLICATION_JSON)
609+
public Response invokeSnapshotAction(@PathParam("id") final int id, ConceptSetSnapshotActionRequest snapshotActionRequest) {
610+
try {
611+
Supplier<ConceptSetExpression> conceptSetExpressionSupplier = () -> getConceptSetExpression(id, snapshotActionRequest.getSourceKey());
612+
conceptSetLockingService.invokeSnapshotAction(id, snapshotActionRequest, conceptSetExpressionSupplier);
613+
return Response.ok().entity("Snapshot action successfully invoked.").build();
614+
} catch (Exception e) {
615+
log.error("Invoke snapshot action failed", e);
616+
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
617+
.entity("Invoke snapshot action failed: " + e.getMessage())
618+
.build();
619+
}
620+
}
621+
622+
@POST
623+
@Path("/locked")
624+
@Consumes(MediaType.APPLICATION_JSON)
625+
@Produces(MediaType.APPLICATION_JSON)
626+
public Response checkIsLockedBatch(IsLockedBatchCheckRequest isLockedBatchCheckRequest) {
627+
IsLockedBatchCheckResponse response = new IsLockedBatchCheckResponse();
628+
try {
629+
List<Integer> ids = isLockedBatchCheckRequest.getConceptSetIds();
630+
Map<Integer, Boolean> lockStatuses = conceptSetLockingService.areLocked(ids);
631+
response.setLockStatus(lockStatuses);
632+
return Response.ok(response).build();
633+
} catch (Exception e) {
634+
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
635+
.entity("Error checking lock statuses: " + e.getMessage())
636+
.build();
637+
}
638+
}
639+
640+
@POST
641+
@Path("/snapshot-items")
642+
@Consumes(MediaType.APPLICATION_JSON)
643+
@Produces(MediaType.APPLICATION_JSON)
644+
public Response getSnapshotItems(GetConceptSetSnapshotItemsRequest request) {
645+
try {
646+
List<ConceptSetExpression.ConceptSetItem> conceptSetItems = conceptSetLockingService.getConceptSetSnapshotItemsBySnapshotId(request.getSnapshotId(), request.getSnapshotItemType());
647+
GetConceptSetSnapshotItemsResponse response = new GetConceptSetSnapshotItemsResponse();
648+
response.setConceptSetItems(conceptSetItems);
649+
return Response.ok(response).build();
650+
} catch (Exception e) {
651+
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
652+
.entity("Error fetching snapshot items: " + e.getMessage())
653+
.build();
654+
}
655+
}
567656

568657
private ConceptSet updateConceptSet(ConceptSet dst, ConceptSet src) {
569658

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.ohdsi.webapi.service.dto;
2+
3+
import org.ohdsi.webapi.service.lock.dto.ConceptSetSnapshotParameters;
4+
5+
public class LockedConceptSetsResponse {
6+
private ConceptSetDTO conceptSet;
7+
private ConceptSetSnapshotParameters snapshotParameters;
8+
9+
public LockedConceptSetsResponse(ConceptSetDTO conceptSet, ConceptSetSnapshotParameters snapshotParameters) {
10+
this.conceptSet = conceptSet;
11+
this.snapshotParameters = snapshotParameters;
12+
}
13+
14+
15+
public ConceptSetSnapshotParameters getSnapshotParameters() {
16+
return snapshotParameters;
17+
}
18+
19+
public void setSnapshotParameters(ConceptSetSnapshotParameters snapshotParameters) {
20+
this.snapshotParameters = snapshotParameters;
21+
}
22+
23+
public ConceptSetDTO getConceptSet() {
24+
return conceptSet;
25+
}
26+
27+
public void setConceptSet(ConceptSetDTO conceptSet) {
28+
this.conceptSet = conceptSet;
29+
}
30+
}

0 commit comments

Comments
 (0)