1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.waarp.openr66.protocol.http.restv2.converters;
22
23 import com.fasterxml.jackson.databind.JsonNode;
24 import com.fasterxml.jackson.databind.node.ArrayNode;
25 import com.fasterxml.jackson.databind.node.ObjectNode;
26 import org.waarp.common.database.exception.WaarpDatabaseSqlException;
27 import org.waarp.common.json.JsonHandler;
28 import org.waarp.common.logging.SysErrLogger;
29 import org.waarp.common.utility.ParametersChecker;
30 import org.waarp.common.xml.XmlUtil;
31 import org.waarp.openr66.context.task.TaskType;
32 import org.waarp.openr66.pojo.Rule;
33 import org.waarp.openr66.pojo.RuleTask;
34 import org.waarp.openr66.protocol.http.restv2.errors.RestError;
35 import org.waarp.openr66.protocol.http.restv2.errors.RestErrorException;
36
37 import java.util.ArrayList;
38 import java.util.Comparator;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Map;
42
43 import static org.waarp.openr66.protocol.http.restv2.RestConstants.RuleFields.*;
44 import static org.waarp.openr66.protocol.http.restv2.errors.RestErrors.*;
45
46
47
48
49
50
51 public final class RuleConverter {
52
53
54
55
56 private RuleConverter() throws InstantiationException {
57 throw new InstantiationException(
58 getClass().getName() + " cannot be instantiated.");
59 }
60
61
62
63
64
65
66 public enum Order {
67
68
69
70 ascName(new Comparator<Rule>() {
71 @Override
72 public final int compare(final Rule t1, final Rule t2) {
73 return t1.getName().compareTo(t2.getName());
74 }
75 }),
76
77
78
79 descName(new Comparator<Rule>() {
80 @Override
81 public final int compare(final Rule t1, final Rule t2) {
82 return -t1.getName().compareTo(t2.getName());
83 }
84 });
85
86
87
88
89 public final Comparator<Rule> comparator;
90
91 Order(final Comparator<Rule> comparator) {
92 this.comparator = comparator;
93 }
94 }
95
96
97
98
99 public enum ModeTrans {
100
101
102
103 send(1),
104
105
106
107 receive(2),
108
109
110
111 sendMD5(3),
112
113
114
115 receiveMD5(4),
116
117
118
119 SENDTHROUGHMODE(5),
120
121
122
123 RECVTHROUGHMODE(6),
124
125
126
127
128 SENDMD5THROUGHMODE(7),
129
130
131
132
133 RECVMD5THROUGHMODE(8);
134
135
136
137
138 public final int code;
139
140 ModeTrans(final int code) {
141 this.code = code;
142 }
143
144
145
146
147
148
149
150
151
152
153
154 public static ModeTrans fromCode(final int code) {
155 for (final ModeTrans mode : values()) {
156 if (mode.code == code) {
157 return mode;
158 }
159 }
160 throw new IllegalArgumentException("Code unknown: " + code);
161 }
162 }
163
164
165
166
167
168
169
170
171
172
173 public static ObjectNode ruleToNode(final Rule rule) {
174 final ObjectNode node = JsonHandler.createObjectNode();
175 node.put(RULE_NAME, rule.getName());
176 node.putArray(HOST_IDS).addAll(getHostIdsArray(rule.getHostids()));
177 node.put(MODE_TRANS, ModeTrans.fromCode(rule.getMode()).name());
178 node.put(RECV_PATH, rule.getRecvPath());
179 node.put(SEND_PATH, rule.getSendPath());
180 node.put(ARCHIVE_PATH, rule.getArchivePath());
181 node.put(WORK_PATH, rule.getWorkPath());
182 node.set(R_PRE_TASKS, getTaskArray(rule.getRPreTasks()));
183 node.set(R_POST_TASKS, getTaskArray(rule.getRPostTasks()));
184 node.set(R_ERROR_TASKS, getTaskArray(rule.getRErrorTasks()));
185 node.set(S_PRE_TASKS, getTaskArray(rule.getSPreTasks()));
186 node.set(S_POST_TASKS, getTaskArray(rule.getSPostTasks()));
187 node.set(S_ERROR_TASKS, getTaskArray(rule.getSErrorTasks()));
188
189 return node;
190 }
191
192
193
194
195
196
197
198
199
200
201
202 public static Rule nodeToNewRule(final ObjectNode object) {
203 Rule emptyRule = null;
204 try {
205 emptyRule = new Rule(null, -1, new ArrayList<String>(), "", "", "", "",
206 new ArrayList<RuleTask>(), new ArrayList<RuleTask>(),
207 new ArrayList<RuleTask>(), new ArrayList<RuleTask>(),
208 new ArrayList<RuleTask>(),
209 new ArrayList<RuleTask>());
210 } catch (final WaarpDatabaseSqlException e) {
211 SysErrLogger.FAKE_LOGGER.syserr(e);
212 }
213
214 return nodeToUpdatedRule(object, emptyRule);
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 public static Rule nodeToUpdatedRule(final ObjectNode object,
232 final Rule oldRule) {
233 final List<RestError> errors = new ArrayList<RestError>();
234
235 final Iterator<Map.Entry<String, JsonNode>> fields = object.fields();
236 while (fields.hasNext()) {
237 final Map.Entry<String, JsonNode> field = fields.next();
238 final String name = field.getKey();
239 final JsonNode value = field.getValue();
240
241 if (name.equalsIgnoreCase(RULE_NAME)) {
242 if (value.isTextual()) {
243 if (oldRule.getName() == null) {
244 oldRule.setName(XmlUtil.getExtraTrimed(value.asText()));
245 } else if (!oldRule.getName()
246 .equals(XmlUtil.getExtraTrimed(value.asText()))) {
247 errors.add(FIELD_NOT_ALLOWED(RULE_NAME));
248 }
249 } else {
250 errors.add(ILLEGAL_FIELD_VALUE(RULE_NAME, XmlUtil.getExtraTrimed(
251 value.toString())));
252 }
253 } else if (name.equalsIgnoreCase(HOST_IDS)) {
254 if (value.isArray()) {
255 final List<String> hosts = new ArrayList<String>();
256 final Iterator<JsonNode> elements = value.elements();
257 while (elements.hasNext()) {
258 final JsonNode element = elements.next();
259 if (element.isTextual()) {
260 hosts.add(XmlUtil.getExtraTrimed(element.asText()));
261 } else {
262 errors.add(ILLEGAL_FIELD_VALUE(HOST_IDS, XmlUtil.getExtraTrimed(
263 value.toString())));
264 }
265 }
266 oldRule.setHostids(hosts);
267 } else {
268 errors.add(ILLEGAL_FIELD_VALUE(HOST_IDS, XmlUtil.getExtraTrimed(
269 value.toString())));
270 }
271 } else if (name.equalsIgnoreCase(MODE_TRANS)) {
272 if (value.isTextual()) {
273 try {
274 final ModeTrans modeTrans =
275 ModeTrans.valueOf(XmlUtil.getExtraTrimed(value.asText()));
276 oldRule.setMode(modeTrans.code);
277 } catch (final IllegalArgumentException e) {
278 errors.add(ILLEGAL_FIELD_VALUE(MODE_TRANS, XmlUtil.getExtraTrimed(
279 value.toString())));
280 }
281 } else {
282 errors.add(ILLEGAL_FIELD_VALUE(MODE_TRANS, XmlUtil.getExtraTrimed(
283 value.toString())));
284 }
285 } else if (name.equalsIgnoreCase(RECV_PATH)) {
286 if (value.isTextual()) {
287 try {
288 oldRule.setRecvPath(XmlUtil.getExtraTrimed(value.asText()));
289 } catch (final WaarpDatabaseSqlException e) {
290 errors.add(ILLEGAL_FIELD_VALUE(RECV_PATH, XmlUtil.getExtraTrimed(
291 value.toString())));
292 }
293 } else {
294 errors.add(ILLEGAL_FIELD_VALUE(RECV_PATH, XmlUtil.getExtraTrimed(
295 value.toString())));
296 }
297 } else if (name.equalsIgnoreCase(SEND_PATH)) {
298 if (value.isTextual()) {
299 try {
300 oldRule.setSendPath(XmlUtil.getExtraTrimed(value.asText()));
301 } catch (final WaarpDatabaseSqlException e) {
302 errors.add(ILLEGAL_FIELD_VALUE(SEND_PATH, XmlUtil.getExtraTrimed(
303 value.toString())));
304 }
305 } else {
306 errors.add(ILLEGAL_FIELD_VALUE(SEND_PATH, XmlUtil.getExtraTrimed(
307 value.toString())));
308 }
309 } else if (name.equalsIgnoreCase(ARCHIVE_PATH)) {
310 if (value.isTextual()) {
311 try {
312 oldRule.setArchivePath(XmlUtil.getExtraTrimed(value.asText()));
313 } catch (final WaarpDatabaseSqlException e) {
314 errors.add(ILLEGAL_FIELD_VALUE(ARCHIVE_PATH, XmlUtil.getExtraTrimed(
315 value.toString())));
316 }
317 } else {
318 errors.add(ILLEGAL_FIELD_VALUE(ARCHIVE_PATH, XmlUtil.getExtraTrimed(
319 value.toString())));
320 }
321 } else if (name.equalsIgnoreCase(WORK_PATH)) {
322 if (value.isTextual()) {
323 try {
324 oldRule.setWorkPath(XmlUtil.getExtraTrimed(value.asText()));
325 } catch (final WaarpDatabaseSqlException e) {
326 errors.add(ILLEGAL_FIELD_VALUE(WORK_PATH, XmlUtil.getExtraTrimed(
327 value.toString())));
328 }
329 } else {
330 errors.add(ILLEGAL_FIELD_VALUE(WORK_PATH, XmlUtil.getExtraTrimed(
331 value.toString())));
332 }
333 } else if (name.equalsIgnoreCase(R_PRE_TASKS)) {
334 if (value.isArray()) {
335 oldRule.setRPreTasks(parseTasks((ArrayNode) value, R_PRE_TASKS));
336 } else {
337 errors.add(ILLEGAL_FIELD_VALUE(R_PRE_TASKS, XmlUtil.getExtraTrimed(
338 value.toString())));
339 }
340 } else if (name.equalsIgnoreCase(R_POST_TASKS)) {
341 if (value.isArray()) {
342 oldRule.setRPostTasks(parseTasks((ArrayNode) value, R_POST_TASKS));
343 } else {
344 errors.add(ILLEGAL_FIELD_VALUE(R_POST_TASKS, XmlUtil.getExtraTrimed(
345 value.toString())));
346 }
347 } else if (name.equalsIgnoreCase(R_ERROR_TASKS)) {
348 if (value.isArray()) {
349 oldRule.setRErrorTasks(parseTasks((ArrayNode) value, R_ERROR_TASKS));
350 } else {
351 errors.add(ILLEGAL_FIELD_VALUE(R_ERROR_TASKS, XmlUtil.getExtraTrimed(
352 value.toString())));
353 }
354 } else if (name.equalsIgnoreCase(S_PRE_TASKS)) {
355 if (value.isArray()) {
356 oldRule.setSPreTasks(parseTasks((ArrayNode) value, S_PRE_TASKS));
357 } else {
358 errors.add(ILLEGAL_FIELD_VALUE(S_PRE_TASKS, XmlUtil.getExtraTrimed(
359 value.toString())));
360 }
361 } else if (name.equalsIgnoreCase(S_POST_TASKS)) {
362 if (value.isArray()) {
363 oldRule.setSPostTasks(parseTasks((ArrayNode) value, S_POST_TASKS));
364 } else {
365 errors.add(ILLEGAL_FIELD_VALUE(S_POST_TASKS, XmlUtil.getExtraTrimed(
366 value.toString())));
367 }
368 } else if (name.equalsIgnoreCase(S_ERROR_TASKS)) {
369 if (value.isArray()) {
370 oldRule.setSErrorTasks(parseTasks((ArrayNode) value, S_ERROR_TASKS));
371 } else {
372 errors.add(ILLEGAL_FIELD_VALUE(S_ERROR_TASKS, XmlUtil.getExtraTrimed(
373 value.toString())));
374 }
375 } else {
376 errors.add(UNKNOWN_FIELD(name));
377 }
378 }
379
380 errors.addAll(checkRequiredFields(oldRule));
381
382 if (errors.isEmpty()) {
383 return oldRule;
384 } else {
385 throw new RestErrorException(errors);
386 }
387 }
388
389
390
391
392
393
394
395
396
397
398 private static ArrayNode getHostIdsArray(final List<String> hostIds) {
399 final ArrayNode array = JsonHandler.createArrayNode();
400 for (final String host : hostIds) {
401 array.add(host);
402 }
403 return array;
404 }
405
406
407
408
409
410
411
412
413 private static ArrayNode getTaskArray(final List<RuleTask> tasks) {
414 final ArrayNode array = JsonHandler.createArrayNode();
415 for (final RuleTask task : tasks) {
416 final ObjectNode object = JsonHandler.createObjectNode();
417 object.put(TASK_TYPE, task.getType());
418 object.put(TASK_ARGUMENTS, task.getPath());
419 object.put(TASK_DELAY, task.getDelay());
420 array.add(object);
421 }
422 return array;
423 }
424
425
426
427
428
429
430
431
432
433
434
435
436 private static List<RestError> checkRequiredFields(final Rule rule) {
437 final List<RestError> errors = new ArrayList<RestError>();
438 if (ParametersChecker.isEmpty(rule.getName())) {
439 errors.add(MISSING_FIELD(RULE_NAME));
440 }
441 if (rule.getMode() == -1) {
442 errors.add(MISSING_FIELD(MODE_TRANS));
443 }
444 return errors;
445 }
446
447
448
449
450
451
452
453
454
455
456
457
458 private static List<RuleTask> parseTasks(final ArrayNode array,
459 final String fieldName) {
460 final List<RuleTask> result = new ArrayList<RuleTask>();
461 final List<RestError> errors = new ArrayList<RestError>();
462
463 final Iterator<JsonNode> elements = array.elements();
464 while (elements.hasNext()) {
465 final JsonNode element = elements.next();
466
467 if (element.isObject()) {
468 final RuleTask task = new RuleTask("", "", 0);
469 final Iterator<Map.Entry<String, JsonNode>> fields = element.fields();
470 while (fields.hasNext()) {
471 final Map.Entry<String, JsonNode> field = fields.next();
472 final String name = field.getKey();
473 final JsonNode value = field.getValue();
474
475 if (name.equalsIgnoreCase(TASK_TYPE)) {
476 if (value.isTextual()) {
477 final String taskType = XmlUtil.getExtraTrimed(value.asText());
478 if (TaskType.isValidTask(taskType)) {
479 task.setType(taskType);
480 } else {
481 errors.add(ILLEGAL_FIELD_VALUE(TASK_TYPE, taskType));
482 }
483 } else {
484 errors.add(ILLEGAL_FIELD_VALUE(TASK_TYPE, XmlUtil.getExtraTrimed(
485 value.toString())));
486 }
487 } else if (name.equalsIgnoreCase(TASK_ARGUMENTS)) {
488 if (value.isTextual()) {
489 task.setPath(XmlUtil.getExtraTrimed(value.asText()));
490 } else {
491 errors.add(ILLEGAL_FIELD_VALUE(TASK_ARGUMENTS,
492 XmlUtil.getExtraTrimed(
493 value.toString())));
494 }
495 } else if (name.equalsIgnoreCase(TASK_DELAY)) {
496 if (value.canConvertToInt() && value.asInt() >= 0) {
497 task.setDelay(value.asInt());
498 } else {
499 errors.add(ILLEGAL_FIELD_VALUE(TASK_DELAY, XmlUtil.getExtraTrimed(
500 value.toString())));
501 }
502 } else {
503 errors.add(UNKNOWN_FIELD(name));
504 }
505 }
506 if (task.getType().isEmpty()) {
507 errors.add(MISSING_FIELD(TASK_TYPE));
508 } else {
509 result.add(task);
510 }
511 } else {
512 errors.add(ILLEGAL_FIELD_VALUE(fieldName, XmlUtil.getExtraTrimed(
513 element.toString())));
514 }
515 }
516
517 if (errors.isEmpty()) {
518 return result;
519 } else {
520 throw new RestErrorException(errors);
521 }
522 }
523
524 }