22
22
import io .cdap .plugin .jms .source .JMSStreamingSourceConfig ;
23
23
24
24
import java .util .Arrays ;
25
+ import java .util .List ;
25
26
import java .util .stream .Collectors ;
26
27
27
28
/**
@@ -60,20 +61,25 @@ public class SchemaValidationUtils {
60
61
WRONG_BODY_DATA_TYPE_FOR_HEADER_ACTION = "The \" header\" field must be of Record data type." ,
61
62
62
63
NOT_SUPPORTED_FIELDS_IN_HEADER_RECORD_ERROR = "Not supported fields set in the header record!" ,
63
- NOT_SUPPORTED_FIELDS_IN_HEADER_RECORD_ACTION = "The field \" header\" support only the fields " +
64
+ NOT_SUPPORTED_FIELDS_IN_HEADER_RECORD_ACTION = "The field \" header\" support only fields: " +
64
65
JMSMessageHeader .describe (),
65
66
66
67
WRONG_PROPERTIES_DATA_TYPE_ERROR = "The field \" properties\" has a not supported data type set!" ,
67
68
WRONG_PROPERTIES_DATA_TYPE_ACTION = "The field \" properties\" is mandatory to be of String or Record data type." ,
68
69
69
70
NOT_SUPPORTED_ROOT_FIELDS_IN_MESSAGE_ERROR = "Not supported root fields in the schema!" ,
70
71
NOT_SUPPORTED_ROOT_FIELDS_IN_MESSAGE_ACTION = "JMS \" Message\" message type supports only \" header\" and " +
71
- "\" properties\" as root fields." ;
72
+ "\" properties\" as root fields." ,
73
+
74
+ HEADER_AND_PROPERTIES_MISSING_IN_MESSAGE_ERROR = "Fields \" Header\" and \" Properties\" are missing!" ,
75
+ HEADER_AND_PROPERTIES_MISSING_IN_MESSAGE_ACTION = "When JMS \" Message\" message type is selected, it is " +
76
+ "mandatory that either \" Header\" or \" Properties\" root fields to be present in schema. " +
77
+ "Set at least one of \" Keep Message Header\" or \" Keep Message Properties\" to true." ;
72
78
73
79
/**
74
80
* Throws an error if schema is null.
75
81
*
76
- * @param schema the user defined schema
82
+ * @param schema the user defined schema
77
83
* @param collector the failure collector
78
84
*/
79
85
public static void validateIfSchemaIsNull (Schema schema , FailureCollector collector ) {
@@ -85,7 +91,7 @@ public static void validateIfSchemaIsNull(Schema schema, FailureCollector collec
85
91
/**
86
92
* Throws an error if the input schema contains any other root fields except of "header", "properties", and "body".
87
93
*
88
- * @param schema the user defined schema
94
+ * @param schema the user defined schema
89
95
* @param collector the failure collector
90
96
*/
91
97
public static void validateIfAnyNotSupportedRootFieldExists (Schema schema , FailureCollector collector ) {
@@ -104,7 +110,7 @@ public static void validateIfAnyNotSupportedRootFieldExists(Schema schema, Failu
104
110
* Throws an error if the input schema does not contain the root field "body". JMS "Message" type is the only message
105
111
* type allowed to have the schema without the root field "body".
106
112
*
107
- * @param schema the user defined schema
113
+ * @param schema the user defined schema
108
114
* @param collector the failure collector
109
115
*/
110
116
public static void validateIfBodyNotInSchema (Schema schema , FailureCollector collector ) {
@@ -123,7 +129,7 @@ public static void validateIfBodyNotInSchema(Schema schema, FailureCollector col
123
129
/**
124
130
* Throws an error if the root field "body" is not of type "string" when JMS "TextMessage" is selected.
125
131
*
126
- * @param schema the user defined schema
132
+ * @param schema the user defined schema
127
133
* @param collector the failure collector
128
134
*/
129
135
public static void validateTextMessageSchema (Schema schema , FailureCollector collector ) {
@@ -138,15 +144,15 @@ public static void validateTextMessageSchema(Schema schema, FailureCollector col
138
144
/**
139
145
* Throws an error if the root field "body" is not of type "string" or "record" when JMS "MapMessage" is selected.
140
146
*
141
- * @param schema the user defined schema
147
+ * @param schema the user defined schema
142
148
* @param collector the failure collector
143
149
*/
144
150
public static void validateMapMessageSchema (Schema schema , FailureCollector collector ) {
145
151
Schema .Type type = schema .getField (JMSMessageParts .BODY ).getSchema ().getType ();
146
152
boolean isTypeString = type .equals (Schema .Type .STRING );
147
153
boolean isTypeRecord = type .equals (Schema .Type .RECORD );
148
154
149
- if (!isTypeString || !isTypeRecord ) {
155
+ if (!isTypeString && !isTypeRecord ) {
150
156
tell (collector , WRONG_BODY_DATA_TYPE_IN_MAP_MESSAGE_ERROR , WRONG_BODY_DATA_TYPE_IN_MAP_MESSAGE_ACTION );
151
157
}
152
158
}
@@ -155,25 +161,35 @@ public static void validateMapMessageSchema(Schema schema, FailureCollector coll
155
161
* Throws an error if the input schema contains any other root fields except of "header", and "properties" when JMS
156
162
* "Message" type is selected.
157
163
*
158
- * @param schema the user defined schema
164
+ * @param schema the user defined schema
159
165
* @param collector the failure collector
160
166
*/
161
167
public static void validateMessageSchema (Schema schema , FailureCollector collector ) {
162
- boolean areNonSupportedRootFieldsPresent = schema
163
- .getFields ()
164
- .stream ()
165
- .map (field -> field .getName ())
166
- .anyMatch (f -> !Arrays .asList (JMSMessageParts .HEADER , JMSMessageParts .PROPERTIES ).contains (f ));
168
+ List <String > fieldNames = schema .getFields ().stream ().map (field -> field .getName ()).collect (Collectors .toList ());
169
+
170
+ boolean areNonSupportedRootFieldsPresent = false ;
171
+ for (String fieldName : fieldNames ) {
172
+ if (Arrays .asList (JMSMessageParts .PROPERTIES , JMSMessageParts .HEADER ).contains (fieldName )) {
173
+ areNonSupportedRootFieldsPresent = true ;
174
+ break ;
175
+ }
176
+ }
167
177
168
178
if (areNonSupportedRootFieldsPresent ) {
169
179
tell (collector , NOT_SUPPORTED_ROOT_FIELDS_IN_MESSAGE_ERROR , NOT_SUPPORTED_ROOT_FIELDS_IN_MESSAGE_ACTION );
170
180
}
181
+
182
+ boolean areHeaderAndPropertiesMissing = !fieldNames .contains (JMSMessageParts .HEADER ) &&
183
+ !fieldNames .contains (JMSMessageParts .PROPERTIES );
184
+ if (areHeaderAndPropertiesMissing ) {
185
+ tell (collector , HEADER_AND_PROPERTIES_MISSING_IN_MESSAGE_ERROR , HEADER_AND_PROPERTIES_MISSING_IN_MESSAGE_ACTION );
186
+ }
171
187
}
172
188
173
189
/**
174
190
* Throws an error if the root field "body" is not of type "array of bytes" when JMS "ObjectMessage" is selected.
175
191
*
176
- * @param schema the user defined schema
192
+ * @param schema the user defined schema
177
193
* @param collector the failure collector
178
194
*/
179
195
public static void validateObjectMessageSchema (Schema schema , FailureCollector collector ) {
@@ -205,15 +221,15 @@ public static void validateObjectMessageSchema(Schema schema, FailureCollector c
205
221
/**
206
222
* Throws an error if the root field "body" is not of type "string" or "record" when JMS "BytesMessage" is selected.
207
223
*
208
- * @param schema the user defined schema
224
+ * @param schema the user defined schema
209
225
* @param collector the failure collector
210
226
*/
211
227
public static void validateBytesMessageSchema (Schema schema , FailureCollector collector ) {
212
228
Schema .Type type = schema .getField (JMSMessageParts .BODY ).getSchema ().getType ();
213
229
boolean isTypeString = type .equals (Schema .Type .STRING );
214
230
boolean isTypeRecord = type .equals (Schema .Type .RECORD );
215
231
216
- if (!isTypeString || !isTypeRecord ) {
232
+ if (!isTypeString && !isTypeRecord ) {
217
233
tell (collector , WRONG_BODY_DATA_TYPE_IN_BYTES_MESSAGE_ERROR , WRONG_BODY_DATA_TYPE_IN_BYTES_MESSAGE_ACTION );
218
234
}
219
235
}
@@ -223,10 +239,15 @@ public static void validateBytesMessageSchema(Schema schema, FailureCollector co
223
239
* contains other fields except of "messageId", "messageTimestamp", "correlationId", "replyTo", "destination",
224
240
* "deliveryNode", "redelivered", "type", "expiration", and "priority".
225
241
*
226
- * @param schema the user defined schema
242
+ * @param schema the user defined schema
227
243
* @param collector the failure collector
228
244
*/
229
245
public static void validateHeaderSchema (Schema schema , FailureCollector collector ) {
246
+
247
+ if (!isFieldPresent (schema , JMSMessageParts .HEADER )) {
248
+ return ;
249
+ }
250
+
230
251
boolean isTypeRecord = schema
231
252
.getField (JMSMessageParts .HEADER )
232
253
.getSchema ()
@@ -238,6 +259,8 @@ public static void validateHeaderSchema(Schema schema, FailureCollector collecto
238
259
}
239
260
240
261
boolean areNonSupportedHeaderFieldsPresent = schema
262
+ .getField (JMSMessageParts .HEADER )
263
+ .getSchema ()
241
264
.getFields ()
242
265
.stream ()
243
266
.map (field -> field .getName ())
@@ -251,40 +274,50 @@ public static void validateHeaderSchema(Schema schema, FailureCollector collecto
251
274
/**
252
275
* Throws an error if the root field "properties" is not of type "string" or "record".
253
276
*
254
- * @param schema the user defined schema
277
+ * @param schema the user defined schema
255
278
* @param collector the failure collector
256
279
*/
257
280
public static void validatePropertiesSchema (Schema schema , FailureCollector collector ) {
281
+
282
+ if (!isFieldPresent (schema , JMSMessageParts .PROPERTIES )) {
283
+ return ;
284
+ }
285
+
258
286
Schema .Type type = schema .getField (JMSMessageParts .PROPERTIES ).getSchema ().getType ();
259
287
boolean isTypeString = type .equals (Schema .Type .STRING );
260
288
boolean isTypeRecord = type .equals (Schema .Type .RECORD );
261
289
262
- if (!isTypeString || !isTypeRecord ) {
290
+ if (!isTypeString && !isTypeRecord ) {
263
291
tell (collector , WRONG_PROPERTIES_DATA_TYPE_ERROR , WRONG_PROPERTIES_DATA_TYPE_ACTION );
264
292
}
265
293
}
266
294
267
295
/**
268
296
* Throws an error and also add the error in the failure collector if one is provided.
269
297
*
270
- * @param collector the failure collector
271
- * @param errorMessage the error message
298
+ * @param collector the failure collector
299
+ * @param errorMessage the error message
272
300
* @param correctiveAction the action that the user should perform to resolve the error
273
301
*/
274
- private static void tell (FailureCollector collector , String errorMessage , String correctiveAction ) {
302
+ public static void tell (FailureCollector collector , String errorMessage , String correctiveAction ) {
275
303
String errorNature = "Error during schema validation" ;
276
304
277
305
if (collector != null ) {
278
306
collector .addFailure (errorNature + ": " + errorMessage , correctiveAction )
279
307
.withConfigProperty (JMSStreamingSourceConfig .NAME_SCHEMA );
308
+ } else {
309
+ throw new RuntimeException (concatenate (errorNature + ": " + errorMessage , correctiveAction ));
280
310
}
311
+ }
281
312
282
- throw new RuntimeException (concatenate (errorNature + ": " + errorMessage , correctiveAction ));
313
+ private static boolean isFieldPresent (Schema schema , String fieldName ) {
314
+ return schema .getField (fieldName ) != null ;
283
315
}
284
316
285
317
/**
286
318
* Concatenates two strings with a space in between
287
- * @param left the left string
319
+ *
320
+ * @param left the left string
288
321
* @param right the right string
289
322
* @return the concatenated string
290
323
*/
0 commit comments