2
2
3
3
import static life .qbic .projectmanagement .application .authorization .ReactiveSecurityContextUtils .applySecurityContext ;
4
4
import static life .qbic .projectmanagement .application .authorization .ReactiveSecurityContextUtils .writeSecurityContext ;
5
+ import static life .qbic .projectmanagement .application .authorization .ReactiveSecurityContextUtils .applySecurityContextMany ;
6
+ import static life .qbic .projectmanagement .application .authorization .ReactiveSecurityContextUtils .writeSecurityContextMany ;
5
7
6
8
import java .nio .ByteBuffer ;
9
+ import java .util .List ;
7
10
import java .util .Objects ;
11
+ import life .qbic .application .commons .SortOrder ;
8
12
import life .qbic .logging .api .Logger ;
9
13
import life .qbic .logging .service .LoggerFactory ;
10
14
import life .qbic .projectmanagement .application .ProjectInformationService ;
11
15
import life .qbic .projectmanagement .application .sample .SampleIdCodeEntry ;
16
+ import life .qbic .projectmanagement .application .sample .SampleInformationService ;
12
17
import life .qbic .projectmanagement .application .sample .SamplePreview ;
18
+ import life .qbic .projectmanagement .domain .model .experiment .ExperimentId ;
13
19
import life .qbic .projectmanagement .domain .model .project .ProjectId ;
14
20
import life .qbic .projectmanagement .domain .model .sample .Sample ;
21
+ import life .qbic .projectmanagement .domain .model .sample .SampleId ;
15
22
import org .springframework .beans .factory .annotation .Autowired ;
16
23
import org .springframework .lang .NonNull ;
17
24
import org .springframework .security .core .context .SecurityContext ;
33
40
@ Service
34
41
public class AsyncProjectServiceImpl implements AsyncProjectService {
35
42
43
+ public static final String ACCESS_DENIED = "Access denied" ;
36
44
private static final Logger log = LoggerFactory .logger (AsyncProjectServiceImpl .class );
37
45
private final ProjectInformationService projectService ;
38
46
private final Scheduler scheduler ;
47
+ private final SampleInformationService sampleInfoService ;
39
48
40
49
public AsyncProjectServiceImpl (@ Autowired ProjectInformationService projectService ,
50
+ @ Autowired SampleInformationService sampleInfoService ,
41
51
@ Autowired Scheduler scheduler ) {
42
52
this .projectService = Objects .requireNonNull (projectService );
53
+ this .sampleInfoService = Objects .requireNonNull (sampleInfoService );
43
54
this .scheduler = Objects .requireNonNull (scheduler );
44
55
}
45
56
@@ -76,22 +87,55 @@ public Flux<ByteBuffer> roCrateSummary(String projectId) {
76
87
throw new RuntimeException ("not implemented" );
77
88
}
78
89
79
- @ Override
80
- public Flux <SamplePreview > getSamplePreviews (String projectId , String experimentId )
81
- throws RequestFailedException {
82
- throw new RuntimeException ("not implemented" );
83
- }
84
90
85
91
@ Override
86
92
public Flux <SamplePreview > getSamplePreviews (String projectId , String experimentId , int offset ,
87
- int limit ) {
88
- throw new RuntimeException ("not implemented" );
93
+ int limit , List <SortOrder > sortOrders , String filter ) {
94
+ SecurityContext securityContext = SecurityContextHolder .getContext ();
95
+ return applySecurityContextMany (Flux .defer (() ->
96
+ fetchSamplePreviews (projectId , experimentId , offset , limit , sortOrders , filter )))
97
+ .subscribeOn (scheduler )
98
+ .transform (original -> writeSecurityContextMany (original , securityContext ))
99
+ .retryWhen (defaultRetryStrategy ());
100
+ }
101
+
102
+ private Flux <SamplePreview > fetchSamplePreviews (String projectId , String experimentId , int offset ,
103
+ int limit , List <SortOrder > sortOrders , String filter ) {
104
+ try {
105
+ return Flux .fromIterable (
106
+ sampleInfoService .queryPreview (ProjectId .parse (projectId ),
107
+ ExperimentId .parse (experimentId ), offset , limit ,
108
+ sortOrders , filter ));
109
+ } catch (Exception e ) {
110
+ log .error ("Error getting sample previews" , e );
111
+ return Flux .error (new RequestFailedException ("Error getting sample previews" ));
112
+ }
89
113
}
90
114
91
115
@ Override
92
116
public Flux <Sample > getSamples (String projectId , String experimentId )
93
117
throws RequestFailedException {
94
- throw new RuntimeException ("not implemented" );
118
+ SecurityContext securityContext = SecurityContextHolder .getContext ();
119
+ return applySecurityContextMany (Flux .defer (() -> fetchSamples (projectId , experimentId )))
120
+ .subscribeOn (scheduler )
121
+ .transform (original -> writeSecurityContextMany (original , securityContext ))
122
+ .retryWhen (defaultRetryStrategy ());
123
+ }
124
+
125
+ // disclaimer: no security context, no scheduler applied
126
+ private Flux <Sample > fetchSamples (String projectId , String experimentId ) {
127
+ try {
128
+ return Flux .fromIterable (
129
+ sampleInfoService .retrieveSamplesForExperiment (ProjectId .parse (projectId ),
130
+ experimentId ));
131
+ } catch (org .springframework .security .access .AccessDeniedException e ) {
132
+ log .error ("Error getting samples" , e );
133
+ return Flux .error (new AccessDeniedException (ACCESS_DENIED ));
134
+ } catch (Exception e ) {
135
+ log .error ("Unexpected exception getting samples" , e );
136
+ return Flux .error (
137
+ new RequestFailedException ("Error getting samples for experiment " + experimentId ));
138
+ }
95
139
}
96
140
97
141
@ Override
@@ -101,9 +145,20 @@ public Flux<Sample> getSamplesForBatch(String projectId, String batchId)
101
145
}
102
146
103
147
@ Override
104
- public Mono <SampleIdCodeEntry > findSampleId (String projectId , String sampleCode )
105
- throws RequestFailedException {
106
- throw new RuntimeException ("not implemented" );
148
+ public Mono <Sample > findSample (String projectId , String sampleId ) {
149
+ return Mono .defer (() -> {
150
+ try {
151
+ return Mono .justOrEmpty (
152
+ sampleInfoService .findSample (ProjectId .parse (projectId ), SampleId .parse (sampleId )));
153
+ } catch (org .springframework .security .access .AccessDeniedException e ) {
154
+ log .error (ACCESS_DENIED , e );
155
+ return Mono .error (new AccessDeniedException (ACCESS_DENIED ));
156
+ } catch (Exception e ) {
157
+ log .error ("Error getting sample for sample " + sampleId , e );
158
+ return Mono .error (
159
+ new RequestFailedException ("Error getting sample for sample " + sampleId ));
160
+ }
161
+ }).subscribeOn (scheduler );
107
162
}
108
163
109
164
@ Override
@@ -153,7 +208,7 @@ private Mono<ProjectUpdateResponse> updateProjectDesign(String projectId, Projec
153
208
} catch (IllegalArgumentException e ) {
154
209
sink .error (new RequestFailedException ("Invalid project id: " + projectId ));
155
210
} catch (org .springframework .security .access .AccessDeniedException e ) {
156
- sink .error (new AccessDeniedException ("Access denied" ));
211
+ sink .error (new AccessDeniedException (ACCESS_DENIED ));
157
212
} catch (RuntimeException e ) {
158
213
sink .error (new RequestFailedException ("Update project design failed" , e ));
159
214
}
0 commit comments