99import java .util .Set ;
1010import java .util .UUID ;
1111import life .qbic .application .commons .SortOrder ;
12+ import life .qbic .projectmanagement .application .ValidationResult ;
1213import life .qbic .projectmanagement .application .batch .SampleUpdateRequest .SampleInformation ;
1314import life .qbic .projectmanagement .application .confounding .ConfoundingVariableService .ConfoundingVariableInformation ;
1415import life .qbic .projectmanagement .application .sample .SamplePreview ;
@@ -222,6 +223,20 @@ Flux<SamplePreview> getSamplePreviews(String projectId, String experimentId, int
222223 */
223224 Mono <Sample > findSample (String projectId , String sampleId );
224225
226+ /**
227+ * Submits multiple validation requests in a single service call.
228+ *
229+ * @param requests a list of one or more {@link ValidationRequest}.
230+ * @return a {@link Flux} of {@link ValidationResponse}, providing the validation results for the
231+ * submitted requests. Exceptions are provided as {@link Flux#error(Throwable)}.
232+ * @throws UnknownRequestException if an unknown request has been used in the service call
233+ * @throws RequestFailedException if the request was not successfully executed
234+ * @throws AccessDeniedException if the user has insufficient rights
235+ * @since 1.10.0
236+ */
237+ Flux <ValidationResponse > validate (List <ValidationRequest > requests ) throws RequestFailedException ;
238+
239+
225240 /**
226241 * Container of an update request for a service call and part of the
227242 * {@link ProjectUpdateRequest}.
@@ -255,14 +270,30 @@ sealed interface ExperimentUpdateResponseBody permits ConfoundingVariables, Expe
255270
256271 }
257272
273+ /**
274+ * A validation request body for information that shall be validated by the service.
275+ * <p>
276+ * Currently, permits:
277+ *
278+ * <ul>
279+ * <li>{@link SampleMetadata}</li>
280+ * </ul>
281+ *
282+ * @since 1.10.0
283+ */
284+ sealed interface ValidationRequestBody permits SampleMetadata {
285+
286+ }
287+
258288
259289 /**
260290 * Cacheable requests provide a unique identifier so cache implementations can unambiguously
261291 * manage the requests.
262292 *
263293 * @since 1.9.0
264294 */
265- sealed interface CacheableRequest permits ProjectUpdateRequest , ExperimentUpdateRequest {
295+ sealed interface CacheableRequest permits ExperimentUpdateRequest , ProjectUpdateRequest ,
296+ ValidationRequest {
266297
267298 /**
268299 * Returns an ID that is unique to the request.
@@ -411,7 +442,8 @@ public List<ExperimentalVariable> experimentalVariables() {
411442 * @param unit the unit for the value of the level. Can be null if no unit is set
412443 * @since 1.9.0
413444 */
414- record VariableLevel (Long variableId , String variableName , String levelValue , @ Nullable String unit ) {
445+ record VariableLevel (Long variableId , String variableName , String levelValue ,
446+ @ Nullable String unit ) {
415447
416448 }
417449
@@ -549,16 +581,15 @@ public List<ConfoundingVariableInformation> confoundingVariables() {
549581 }
550582 }
551583
552-
553584 /**
554585 * A service request to update an experiment
555586 *
556587 * @param projectId the project's identifier. The project containing the experiment.
557588 * @param experimentId the experiment's identifier
558589 * @param body the request body containing information on what was updated
559- * @param requestId The identifier of the request. Please use
560- * {@link #ExperimentUpdateRequest(String, String ,
561- * ExperimentUpdateRequestBody)} if it is not determined yet.
590+ * @param requestId the request ID, needs to be provided by the client and will be referenced
591+ * in the response. If <code>null</code> or {@link String#isBlank()} is true ,
592+ * then a random UUID is assigned with {@link UUID#randomUUID()}
562593 * @since 1.9.0
563594 */
564595 record ExperimentUpdateRequest (String projectId , String experimentId ,
@@ -662,26 +693,44 @@ record ProjectCreationResponse(String projectId) {
662693 *
663694 * @param projectId the project's id
664695 * @param requestBody the information to be updated.
696+ * @param requestId the request ID, needs to be provided by the client and will be referenced in
697+ * the response. If <code>null</code> or {@link String#isBlank()} is true, then
698+ * a random UUID is assigned with {@link UUID#randomUUID()}.
665699 * @since 1.9.0
666700 */
667701 record ProjectUpdateRequest (String projectId , ProjectUpdateRequestBody requestBody ,
668- String id ) implements CacheableRequest {
702+ String requestId ) implements CacheableRequest {
703+
704+ public ProjectUpdateRequest {
705+ if (projectId == null ) {
706+ throw new IllegalArgumentException ("Project ID cannot be null" );
707+ }
708+ if (projectId .isBlank ()) {
709+ throw new IllegalArgumentException ("Project ID cannot be blank" );
710+ }
711+ if (requestId != null && requestId .isBlank ()) {
712+ requestId = null ;
713+ }
714+ if (requestId == null ) {
715+ requestId = UUID .randomUUID ().toString ();
716+ }
717+ }
718+
669719
670720 public ProjectUpdateRequest (String projectId , ProjectUpdateRequestBody requestBody ) {
671721 this (projectId , requestBody , UUID .randomUUID ().toString ());
672722 }
673723
674- @ Override
675- public String requestId () {
676- return id ;
677- }
678724 }
679725
680726 /**
681727 * A service response from an update project information request.
682728 *
683729 * @param projectId the project's id
684730 * @param responseBody the information that was updated.
731+ * @param requestId the request ID, needs to be provided by the client and will be referenced
732+ * in the response. If <code>null</code> or {@link String#isBlank()} is true,
733+ * then a random UUID is assigned with {@link UUID#randomUUID()}
685734 * @since 1.9.0
686735 */
687736 record ProjectUpdateResponse (String projectId , ProjectUpdateResponseBody responseBody ,
@@ -697,6 +746,9 @@ record ProjectUpdateResponse(String projectId, ProjectUpdateResponseBody respons
697746 if (requestId != null && requestId .isBlank ()) {
698747 requestId = null ;
699748 }
749+ if (requestId == null ) {
750+ requestId = UUID .randomUUID ().toString ();
751+ }
700752 }
701753
702754 /**
@@ -709,21 +761,62 @@ public Optional<String> retrieveRequestId() {
709761 return Optional .ofNullable (requestId );
710762 }
711763
712- /**
713- * Returns the requestId, can be null.
714- *
715- * @return Returns the requestId, if no requestId is set, returns null.
716- */
717- @ Override
718- public String requestId () {
719- return requestId ;
720- }
721-
722764 boolean hasRequestId () {
723765 return nonNull (requestId );
724766 }
725767 }
726768
769+ /**
770+ * The actual request container for metadata validation.
771+ * <p>
772+ * A validation request contains a {@link ValidationRequestBody} with the actual metadata to be
773+ * validated, next to the project ID and the request ID.
774+ *
775+ * @param projectId the project ID of the project the metadata shall be validated for
776+ * @param requestBody the actual metadata container with the information to be validated
777+ * @param requestId the request ID, needs to be provided by the client and will be referenced in
778+ * the response. If <code>null</code> or {@link String#isBlank()} is true, then
779+ * a random UUID is assigned with {@link UUID#randomUUID()}
780+ * @since 1.10.0
781+ */
782+ record ValidationRequest (String projectId , ValidationRequestBody requestBody ,
783+ String requestId ) implements CacheableRequest {
784+
785+ public ValidationRequest {
786+ if (projectId == null ) {
787+ throw new IllegalArgumentException ("Project ID cannot be null" );
788+ }
789+ if (projectId .isBlank ()) {
790+ throw new IllegalArgumentException ("Project ID cannot be blank" );
791+ }
792+ if (requestId != null && requestId .isBlank ()) {
793+ requestId = null ;
794+ }
795+ if (requestId == null ) {
796+ requestId = UUID .randomUUID ().toString ();
797+ }
798+ }
799+ }
800+
801+ /**
802+ * The response to a corresponding {@link ValidationRequest} with information about the actual
803+ * validation result.
804+ * <p>
805+ * The result itself is provided in the {@link ValidationResult} property.
806+ *
807+ * @param requestId the original ID of the request from {@link ValidationRequest}
808+ * @param result the validation report provided as {@link ValidationResult}
809+ * @since 1.10.0
810+ */
811+ record ValidationResponse (String requestId , ValidationResult result ) {
812+
813+ public ValidationResponse {
814+ if (requestId == null || requestId .isBlank ()) {
815+ throw new IllegalArgumentException ("Request ID cannot be null or blank" );
816+ }
817+ }
818+ }
819+
727820 /**
728821 * Exception to indicate that the service did not recognise the request.
729822 *
0 commit comments