|
86 | 86 | * Can now follow reference links in in properties (with a cache mechanism to reduce the calls to ServiceNow) |
87 | 87 | * Can now use variables ${xxx} in ini properties |
88 | 88 | * Use CIs operational status to determine if Archi elements should be created/updated or removed |
89 | | - * Allow to specify the import mode: full, create_only, update_only, create_or_update_only and remove_only |
| 89 | + * Allow to specify the import mode: full, create_only, update_only, create_or_update_only and remove_only |
| 90 | + * |
| 91 | + * version 1.4: 26/09/2018 |
| 92 | + * continue in case we cannot follow a link |
| 93 | + * |
| 94 | + * version 1.5: 26/10/2018 |
| 95 | + * add "filter" option |
90 | 96 | * |
91 | 97 | * TODO: retrieve the applications and business services |
92 | 98 | * TODO: use commands to allow rollback |
93 | 99 | * TODO: validate that relations are permitted before creating them |
| 100 | + * TODO: add an option to continue in case of error --> but count the number of errors and show this counter on the summary popup |
| 101 | + * TODO: transform progressbar window: show all tables/relationships with one progress bar in front of each table/relationship |
| 102 | + * TODO: transform progressbar window: show same look and feel that database plugin |
| 103 | + * TOTO: add cancel button |
| 104 | + * TODO: add variable ${on_error:xxxxxxx) ou ${on_empty:xxxxx} |
| 105 | + * |
94 | 106 | */ |
95 | 107 |
|
96 | 108 | public class MyImporter implements ISelectedModelImporter { |
97 | | - static String SNowPluginVersion = "1.3"; |
| 109 | + static String SNowPluginVersion = "1.5"; |
98 | 110 | static String title = "ServiceNow import plugin v" + SNowPluginVersion; |
99 | 111 |
|
100 | 112 | Logger logger; |
@@ -135,6 +147,7 @@ public void doImport(IArchimateModel model) throws IOException { |
135 | 147 | String generalArchiElementsName = null; |
136 | 148 | String generalArchiElementsDocumentation = null; |
137 | 149 | String generalArchiElementsFolder = null; |
| 150 | + String generalArchiElementsFilter = null; |
138 | 151 | String generalArchiElementsImportMode = null; |
139 | 152 |
|
140 | 153 | // general relations properties |
@@ -244,6 +257,7 @@ public void doImport(IArchimateModel model) throws IOException { |
244 | 257 | generalArchiElementsName = this.iniProperties.getString("archi.elements.*.name", "sys_class_name"); |
245 | 258 | generalArchiElementsDocumentation = this.iniProperties.getString("archi.elements.*.documentation", "short_description"); |
246 | 259 | generalArchiElementsFolder = this.iniProperties.getString("archi.elements.*.folder", "sys_class_name"); |
| 260 | + generalArchiElementsFilter = this.iniProperties.getString("archi.elements.*.filter", ""); |
247 | 261 | generalArchiElementsImportMode = this.iniProperties.getString("archi.elements.*.import_mode", "full"); |
248 | 262 | if ( !generalArchiElementsImportMode.equals("full") && !generalArchiElementsImportMode.equals("create_or_update_only") && !generalArchiElementsImportMode.equals("create_only") && !generalArchiElementsImportMode.equals("update_only") && !generalArchiElementsImportMode.equals("remove_only") ) { |
249 | 263 | @SuppressWarnings("unused") |
@@ -382,7 +396,7 @@ public void doImport(IArchimateModel model) throws IOException { |
382 | 396 | urlBuilder.append(","); |
383 | 397 | urlBuilder.append(field); |
384 | 398 | } |
385 | | - |
| 399 | + |
386 | 400 | String archiElementsImportMode = this.iniProperties.getString("archi.elements."+tableName+".importMode", generalArchiElementsImportMode); |
387 | 401 | if ( !archiElementsImportMode.equals("full") && !archiElementsImportMode.equals("create_or_update_only") && !archiElementsImportMode.equals("create_only") && !archiElementsImportMode.equals("update_only") && !generalArchiElementsImportMode.equals("remove_only") ) { |
388 | 402 | @SuppressWarnings("unused") |
@@ -431,11 +445,24 @@ public void doImport(IArchimateModel model) throws IOException { |
431 | 445 | // operational_status = 1 if create or update only |
432 | 446 | // operational_status = 2 if remove_only |
433 | 447 | // and no filter if create, update and remove |
| 448 | + StringBuilder sysparmQuery = new StringBuilder(); |
434 | 449 | if ( generalArchiElementsImportMode.equals("create_or_update_only") || generalArchiElementsImportMode.equals("create_only") || generalArchiElementsImportMode.equals("update_only") ) |
435 | | - urlBuilder.append("&sysparm_query=operational_status="+this.OPERATIONAL); |
| 450 | + sysparmQuery.append("operational_status="+this.OPERATIONAL); |
436 | 451 | else if ( generalArchiElementsImportMode.equals("remove_only") ) |
437 | | - urlBuilder.append("&sysparm_query=operational_status="+this.NON_OPERATIONAL); |
438 | | - |
| 452 | + sysparmQuery.append("operational_status="+this.NON_OPERATIONAL); |
| 453 | + |
| 454 | + String archiElementsFilter = this.iniProperties.getString("archi.elements."+tableName+".filter", generalArchiElementsFilter); |
| 455 | + if ( archiElementsFilter.length() != 0 ) { |
| 456 | + if ( sysparmQuery.length() != 0 ) |
| 457 | + sysparmQuery.append(","); |
| 458 | + sysparmQuery.append(archiElementsFilter); |
| 459 | + } |
| 460 | + |
| 461 | + if ( sysparmQuery.length() != 0 ) { |
| 462 | + urlBuilder.append("&sysparm_query="); |
| 463 | + urlBuilder.append(sysparmQuery); |
| 464 | + } |
| 465 | + |
439 | 466 | this.logger.debug(" Generated URL is " + urlBuilder.toString()); |
440 | 467 |
|
441 | 468 | // we invoke the ServiceNow web service |
@@ -1162,17 +1189,25 @@ private String getJsonField(JsonNode node, String fieldName, String defaultValue |
1162 | 1189 | else { |
1163 | 1190 | // we invoke the ServiceNow web service |
1164 | 1191 | this.logger.trace(" Following reference link to URL "+linkURL); |
1165 | | - MyConnection connection = new MyConnection(this.proxyHost, this.proxyPort, this.proxyUser, this.proxyPassword); |
1166 | | - connection.setLogger(this.logger); |
1167 | | - String linkContent = connection.get(subFields[column], linkURL, this.serviceNowUser, this.serviceNowPassword); |
1168 | | - JsonFactory jsonFactory = new MappingJsonFactory(); |
1169 | | - try ( JsonParser jsonParser = jsonFactory.createJsonParser(linkContent) ) { |
1170 | | - jsonNode = jsonParser.readValueAsTree().get("result"); |
1171 | | - this.referenceLinkCache.put(linkURL, jsonNode); |
1172 | | - } catch (JsonParseException err) { |
1173 | | - this.logger.error("Failed to parse JSON got from ServiceNow.", err); |
1174 | | - jsonNode = null; |
1175 | | - break; |
| 1192 | + try { |
| 1193 | + MyConnection connection = new MyConnection(this.proxyHost, this.proxyPort, this.proxyUser, this.proxyPassword); |
| 1194 | + connection.setLogger(this.logger); |
| 1195 | + String linkContent = connection.get(subFields[column], linkURL, this.serviceNowUser, this.serviceNowPassword); |
| 1196 | + JsonFactory jsonFactory = new MappingJsonFactory(); |
| 1197 | + try ( JsonParser jsonParser = jsonFactory.createJsonParser(linkContent) ) { |
| 1198 | + jsonNode = jsonParser.readValueAsTree().get("result"); |
| 1199 | + this.referenceLinkCache.put(linkURL, jsonNode); |
| 1200 | + } catch (JsonParseException err) { |
| 1201 | + this.logger.error("Failed to parse JSON got from ServiceNow.", err); |
| 1202 | + jsonNode = null; |
| 1203 | + //TODO: ++error_count; |
| 1204 | + break; |
| 1205 | + } |
| 1206 | + } catch (MyException | IOException err2) { |
| 1207 | + this.logger.error("Failed to get URL from ServiceNow.", err2); |
| 1208 | + jsonNode = null; |
| 1209 | + //TODO: ++error_count; |
| 1210 | + break; |
1176 | 1211 | } |
1177 | 1212 | } |
1178 | 1213 | } |
|
0 commit comments