Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <sara xmlns="http://www.automic.com/sara/snsc">
- <references>
- <variable_types>
- <var_type value="1">Yes / No</var_type>
- <var_type value="2">Multi Line Text</var_type>
- <var_type value="3">Multiple Choice</var_type>
- <var_type value="4">Numeric Scale</var_type>
- <var_type value="18">Lookup Select Box</var_type>
- <var_type value="5">Select Box</var_type>
- <var_type value="6">Single Line Text</var_type>
- <var_type value="7">CheckBox</var_type>
- <var_type value="8">Reference</var_type>
- <var_type value="9">Date</var_type>
- <var_type value="10">Date/Time</var_type>
- <var_type value="11">Label</var_type>
- <var_type value="12">Break</var_type>
- <var_type value="14">Macro</var_type>
- <var_type value="15">UI Page</var_type>
- <var_type value="16">Wide Single Line Text</var_type>
- <var_type value="17">Macro with Label</var_type>
- <var_type value="21">List Collector</var_type>
- <var_type value="22">Lookup Multiple Choice</var_type>
- <var_type value="23">HTML</var_type>
- </variable_types>
- </references>
- <package name="snsc" version="1.0-SNAPSHOT">
- <description/>
- <system_properties>
- <category>
- <name>Automic</name>
- <title>This category consists of all SARA OAuth client settings</title>
- <properties>
- <property>
- <suffix>mid_server</suffix>
- <description>MID Server name to use</description>
- <type>string</type>
- <value/>
- <ignore_cache>false</ignore_cache>
- <private>false</private>
- </property>
- <property>
- <suffix>workflow_timeout</suffix>
- <description>Specifies the time during that the status of service/workflow is checked continuesly. The interval of checking is specified by the parameter x_ausgh_snsc.workflow_delay. If the value equals 0, the duration time will be forever.
- *Note: This value is second(s).</description>
- <type>string</type>
- <value>0</value>
- <ignore_cache>false</ignore_cache>
- <private>false</private>
- </property>
- <property>
- <suffix>workflow_delay</suffix>
- <description>Specifies the interval of checking a workflow/service's status. If the value equals 0, the time interval will be 60.
- *Note: This value is second(s).</description>
- <type>string</type>
- <value>20</value>
- <ignore_cache>false</ignore_cache>
- <private>false</private>
- </property>
- <property>
- <suffix>rest_request_timeout</suffix>
- <description>Specifies the amount of time the instance waits for a response from the web service provider. If the value equals 0, the timeout will be 60.
- *Note: This value is second(s).</description>
- <type>string</type>
- <value>120</value>
- <ignore_cache>false</ignore_cache>
- <private>false</private>
- </property>
- <property>
- <suffix>service_active</suffix>
- <description>The default active status of services after importing. Can be "true" for active and "false" for inactive.</description>
- <type>boolean</type>
- <value>true</value>
- <ignore_cache>false</ignore_cache>
- <private>false</private>
- </property>
- </properties>
- </category>
- </system_properties>
- <tables>
- <table>
- <name>x_ausgh_snsc_sara_oauth</name>
- <label>Sara OAuth</label>
- <extends_table/>
- <user_role>x_ausgh_snsc.user</user_role>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>u_access_token</name>
- <type>string</type>
- <label>Access Token</label>
- <max_length>1000</max_length>
- <hint>Access token from OAuth</hint>
- </column>
- <column>
- <name>u_refresh_token</name>
- <type>string</type>
- <label>Refresh Token</label>
- <max_length>1000</max_length>
- <hint>Refresh token from OAuth</hint>
- </column>
- <column>
- <name>u_token_expiry</name>
- <type>string</type>
- <label>Token Expiry</label>
- <max_length>40</max_length>
- <hint>The lived time of token from OAuth</hint>
- </column>
- <column>
- <name>u_token_type</name>
- <type>string</type>
- <label>Token Type</label>
- <max_length>40</max_length>
- <hint>The type of token from OAuth</hint>
- </column>
- <column>
- <name>u_user</name>
- <type>string</type>
- <label>Technical User</label>
- <max_length>1000</max_length>
- <display>true</display>
- <hint>The AE technical user own this token</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sara_variable</name>
- <label>Sara Variable</label>
- <extends_table>item_option_new</extends_table>
- <user_role>x_ausgh_snsc.user</user_role>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>u_name</name>
- <type>string</type>
- <label>Actual Name</label>
- <max_length>1000</max_length>
- <display>true</display>
- <hint>The actual name of variable in AE</hint>
- </column>
- <column>
- <name>u_readonly</name>
- <type>boolean</type>
- <label>Read Only</label>
- <max_length>40</max_length>
- <hint>This is read-only field or not</hint>
- </column>
- <column>
- <name>u_is_password</name>
- <type>boolean</type>
- <label>Is Password</label>
- <max_length>40</max_length>
- <hint>This field is marked as password or not</hint>
- </column>
- <column>
- <name>u_is_lookup</name>
- <type>boolean</type>
- <label>Is Lookup Control</label>
- <max_length>40</max_length>
- <hint>This control is lookup control or not</hint>
- </column>
- <column>
- <name>u_hash</name>
- <type>string</type>
- <label>Sara Variable Hash</label>
- <max_length>32</max_length>
- <hint>The hash of current lookup values of control from SAPI</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sara_definition</name>
- <label>Sara Definition</label>
- <extends_table/>
- <user_role>x_ausgh_snsc.user</user_role>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>u_name</name>
- <type>string</type>
- <label>Name</label>
- <max_length>1000</max_length>
- <display>true</display>
- <hint>Name of catalog item or category</hint>
- </column>
- <column>
- <name>u_consume_url</name>
- <type>string</type>
- <label>Consume URL</label>
- <max_length>1000</max_length>
- <hint>Consume URL of SAPI service</hint>
- </column>
- <column>
- <name>u_sc_item</name>
- <type>reference</type>
- <label>Service Catalog Item</label>
- <max_length>32</max_length>
- <reference>sc_cat_item</reference>
- <reference_cascade_rule>delete</reference_cascade_rule>
- <hint>The corresponding Catalog item in sc_cat_item table</hint>
- </column>
- <column>
- <name>u_service_catalog_category</name>
- <type>reference</type>
- <label>Service Catalog Category</label>
- <max_length>32</max_length>
- <reference>sc_category</reference>
- <reference_cascade_rule>delete</reference_cascade_rule>
- <hint>The corresponding Category in sc_cateogry table</hint>
- </column>
- <column>
- <name>u_var_set</name>
- <type>reference</type>
- <label>Sara Variable Set</label>
- <max_length>32</max_length>
- <reference>item_option_new_set</reference>
- <hint>The corresponding Variable Set in item_option_new_set table</hint>
- </column>
- <column>
- <name>u_parent</name>
- <type>reference</type>
- <label>Parent Category</label>
- <max_length>32</max_length>
- <reference>sc_category</reference>
- <hint>Reference to parent category, for catalog item it's the parent category (or catalog in SAPI term), for category it's the target category when it was imported.</hint>
- </column>
- <column>
- <name>u_type</name>
- <type>string</type>
- <label>Sara Type</label>
- <max_length>40</max_length>
- <hint>Type of entity. Can be catalog, service, category</hint>
- </column>
- <column>
- <name>u_hash</name>
- <type>string</type>
- <label>Sara Object Hash</label>
- <max_length>32</max_length>
- <hint>The hash of response data from SAPI for Catalog Item</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sara_lookup</name>
- <label>Sara Lookup</label>
- <extends_table/>
- <user_role>catalog</user_role>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>u_key</name>
- <type>string</type>
- <label>Key</label>
- <max_length>203</max_length>
- <hint>The key value of lookup value</hint>
- </column>
- <column>
- <name>u_display_name</name>
- <type>string</type>
- <label>Display Name</label>
- <display>true</display>
- <max_length>1023</max_length>
- <hint>The display name value of lookup value</hint>
- </column>
- <column>
- <name>u_control_id</name>
- <type>reference</type>
- <label>Lookup Control ID</label>
- <max_length>32</max_length>
- <reference>x_ausgh_snsc_sara_variable</reference>
- <reference_cascade_rule>delete</reference_cascade_rule>
- <hint>The sys_id of control which owns this lookup value</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sara_config</name>
- <label>Sara Configuration</label>
- <extends_table/>
- <user_role>x_ausgh_snsc.user</user_role>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>u_client_id</name>
- <type>string</type>
- <label>OAuth Client ID</label>
- <max_length>1000</max_length>
- <display>true</display>
- <hint>Identity of OAuth client</hint>
- </column>
- <column>
- <name>u_client_secret</name>
- <type>string</type>
- <label>OAuth Client Secret</label>
- <max_length>1000</max_length>
- <hint>OAuth client secret string</hint>
- </column>
- <column>
- <name>u_technical_user</name>
- <type>string</type>
- <label>Technical User</label>
- <max_length>1000</max_length>
- <hint>The Technical User for authenticating with OAuth Server</hint>
- </column>
- <column>
- <name>u_sapi_endpoint</name>
- <type>string</type>
- <label>SAPI Endpoint</label>
- <max_length>1000</max_length>
- <hint>URL to SAPI root endpoint</hint>
- </column>
- <column>
- <name>u_token_endpoint</name>
- <type>string</type>
- <label>OAuth Token Endpoint</label>
- <max_length>1000</max_length>
- <hint>Endpoint for token requesting/refreshing</hint>
- </column>
- <column>
- <name>u_auth_endpoint</name>
- <type>string</type>
- <label>OAuth Authorization Endpoint</label>
- <max_length>1000</max_length>
- <hint>Authorization endpoint for OAuth authentication</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sc_catalog_ist</name>
- <label>Service Catalog ImportSet</label>
- <extends_table>sys_import_set_row</extends_table>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>title</name>
- <type>translated_field</type>
- <label>Title</label>
- <max_length>100</max_length>
- <hint>Title</hint>
- <mandatory>true</mandatory>
- <display>true</display>
- </column>
- <column>
- <name>active</name>
- <type>boolean</type>
- <label>Active</label>
- <max_length>40</max_length>
- <hint/>
- </column>
- <column>
- <name>description</name>
- <type>translated_text</type>
- <label>Description</label>
- <max_length>4000</max_length>
- <hint>Description</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sc_category_ist</name>
- <label>Service Category ImportSet</label>
- <extends_table>sys_import_set_row</extends_table>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>title</name>
- <type>translated_text</type>
- <label>Title</label>
- <max_length>100</max_length>
- <hint>Title</hint>
- <mandatory>true</mandatory>
- <display>true</display>
- </column>
- <column>
- <name>homepage_renderer</name>
- <type>string</type>
- <label>Homepage Renderer</label>
- <max_length>32</max_length>
- <hint>Homepage Renderer</hint>
- </column>
- <column>
- <name>active</name>
- <type>boolean</type>
- <label>Active</label>
- <max_length>40</max_length>
- <hint/>
- </column>
- <column>
- <name>description</name>
- <type>translated_text</type>
- <label>Description</label>
- <max_length>4000</max_length>
- <hint>Description</hint>
- </column>
- <column>
- <name>parent</name>
- <type>string</type>
- <label>Parent</label>
- <max_length>32</max_length>
- <hint>Parent</hint>
- </column>
- <column>
- <name>sc_catalog</name>
- <type>string</type>
- <label>Catalog</label>
- <max_length>32</max_length>
- <hint>Catalog</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sc_cat_item_ist</name>
- <label>Catalog Item ImportSet</label>
- <extends_table>sys_import_set_row</extends_table>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>name</name>
- <type>translated_text</type>
- <label>Name</label>
- <max_length>100</max_length>
- <hint>Name</hint>
- <mandatory>true</mandatory>
- <display>true</display>
- </column>
- <column>
- <name>category</name>
- <type>string</type>
- <label>Category Reference</label>
- <max_length>32</max_length>
- <hint>Category Reference</hint>
- </column>
- <column>
- <name>active</name>
- <type>boolean</type>
- <label>Active</label>
- <max_length>40</max_length>
- <hint/>
- </column>
- <column>
- <name>short_description</name>
- <type>translated_text</type>
- <label>Short Description</label>
- <max_length>200</max_length>
- <hint>Short Description</hint>
- </column>
- <column>
- <name>description</name>
- <type>translated_html</type>
- <label>Description</label>
- <max_length>8000</max_length>
- <hint>Description</hint>
- </column>
- <column>
- <name>custom_cart</name>
- <type>string</type>
- <label>Custom Cart</label>
- <max_length>32</max_length>
- <hint>Custom Cart Reference</hint>
- </column>
- <column>
- <name>use_sc_layout</name>
- <type>boolean</type>
- <label>Use Catalog Layout</label>
- <max_length>40</max_length>
- <hint/>
- </column>
- <column>
- <name>no_quantity</name>
- <type>boolean</type>
- <label>No Quantity</label>
- <max_length>40</max_length>
- <hint/>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_item_option_new_set_ist</name>
- <label>Variable Set ImportSet</label>
- <extends_table>sys_import_set_row</extends_table>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>name</name>
- <type>string</type>
- <label>Name</label>
- <max_length>40</max_length>
- <hint>Name</hint>
- <mandatory>true</mandatory>
- <display>true</display>
- </column>
- <column>
- <name>description</name>
- <type>string</type>
- <label>Description</label>
- <max_length>4000</max_length>
- <hint>Description</hint>
- </column>
- <column>
- <name>title</name>
- <type>translated_field</type>
- <label>Title</label>
- <max_length>80</max_length>
- <hint>Title</hint>
- </column>
- <column>
- <name>sys_name</name>
- <type>string</type>
- <label>Display Name</label>
- <max_length>255</max_length>
- <hint>Display Name</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_io_set_item_ist</name>
- <label>Catalog Variable Set ImportSet</label>
- <extends_table>sys_import_set_row</extends_table>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>sc_cat_item</name>
- <type>string</type>
- <label>Catalog Item</label>
- <max_length>32</max_length>
- <hint>Catalog Item</hint>
- <mandatory>true</mandatory>
- <display>true</display>
- </column>
- <column>
- <name>item_option_new_set</name>
- <type>string</type>
- <label>Variable Set</label>
- <max_length>32</max_length>
- <hint>Variable Set</hint>
- <mandatory>true</mandatory>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sara_definition_ist</name>
- <label>Sara Definition ImportSet</label>
- <user_role>x_ausgh_snsc.user</user_role>
- <is_extendable>false</is_extendable>
- <extends_table>sys_import_set_row</extends_table>
- <dictionary_entries>
- <column>
- <name>u_name</name>
- <type>string</type>
- <label>Name</label>
- <max_length>1000</max_length>
- <display>true</display>
- <hint>Name of catalog item or category</hint>
- <mandatory>true</mandatory>
- </column>
- <column>
- <name>u_consume_url</name>
- <type>string</type>
- <label>Consume URL</label>
- <max_length>1000</max_length>
- <hint>Consume URL of SAPI service</hint>
- </column>
- <column>
- <name>u_sc_item</name>
- <type>string</type>
- <label>Service Catalog Item</label>
- <max_length>32</max_length>
- <hint>The corresponding Catalog item in sc_cat_item table</hint>
- </column>
- <column>
- <name>u_service_catalog_category</name>
- <type>string</type>
- <label>Service Catalog Category</label>
- <max_length>32</max_length>
- <hint>The corresponding Category in sc_cateogry table</hint>
- </column>
- <column>
- <name>u_var_set</name>
- <type>string</type>
- <label>Sara Variable Set</label>
- <max_length>32</max_length>
- <hint>The corresponding Variable Set in item_option_new_set table</hint>
- </column>
- <column>
- <name>u_parent</name>
- <type>string</type>
- <label>Parent Category</label>
- <max_length>32</max_length>
- <hint>Reference to parent category, for catalog item it's the parent category (or catalog in SAPI term), for category it's the target category when it was imported.</hint>
- </column>
- <column>
- <name>u_type</name>
- <type>string</type>
- <label>Sara Type</label>
- <max_length>40</max_length>
- <hint>Type of entity. Can be catalog, service, category</hint>
- </column>
- <column>
- <name>u_hash</name>
- <type>string</type>
- <label>Sara Object Hash</label>
- <max_length>32</max_length>
- <hint>The hash of response data from SAPI for Catalog Item</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sara_variable_ist</name>
- <label>Sara Variable ImportSet</label>
- <extends_table>sys_import_set_row</extends_table>
- <user_role>x_ausgh_snsc.user</user_role>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>u_name</name>
- <type>string</type>
- <label>Actual Name</label>
- <max_length>1000</max_length>
- <display>true</display>
- <hint>The actual name of variable in AE</hint>
- <mandatory>true</mandatory>
- <display>true</display>
- </column>
- <column>
- <name>u_readonly</name>
- <type>boolean</type>
- <label>Read Only</label>
- <max_length>40</max_length>
- <hint>This is read-only field or not</hint>
- </column>
- <column>
- <name>u_is_password</name>
- <type>boolean</type>
- <label>Is Password</label>
- <max_length>40</max_length>
- <hint>This field is marked as password or not</hint>
- </column>
- <column>
- <name>u_is_lookup</name>
- <type>boolean</type>
- <label>Is Lookup Control</label>
- <max_length>40</max_length>
- <hint>This control is lookup control or not</hint>
- </column>
- <column>
- <name>u_hash</name>
- <type>string</type>
- <label>Sara Variable Hash</label>
- <max_length>32</max_length>
- <hint>The hash of current lookup values of control from SAPI</hint>
- </column>
- <column>
- <name>variable_set</name>
- <type>string</type>
- <label>Variable Set</label>
- <max_length>32</max_length>
- <hint>Variable Set</hint>
- </column>
- <column>
- <name>type</name>
- <type>string</type>
- <label>Type</label>
- <max_length>40</max_length>
- <hint>Type</hint>
- </column>
- <column>
- <name>macro</name>
- <type>string</type>
- <label>Macro</label>
- <max_length>32</max_length>
- <hint>Macro</hint>
- </column>
- <column>
- <name>name</name>
- <type>string</type>
- <label>Name</label>
- <max_length>40</max_length>
- <hint>Name</hint>
- </column>
- <column>
- <name>cat_item</name>
- <type>string</type>
- <label>Catalog Item</label>
- <max_length>32</max_length>
- <hint>Catalog Item</hint>
- </column>
- <column>
- <name>variable_set</name>
- <type>string</type>
- <label>Variable Set</label>
- <max_length>32</max_length>
- <hint>Variable Set</hint>
- </column>
- <column>
- <name>help_text</name>
- <type>translated_text</type>
- <label>Help text</label>
- <max_length>4000</max_length>
- <hint>Help text</hint>
- </column>
- <column>
- <name>show_help</name>
- <type>boolean</type>
- <label>Show help</label>
- <max_length>40</max_length>
- <hint>Show help</hint>
- </column>
- <column>
- <name>include_none</name>
- <type>boolean</type>
- <label>Include none</label>
- <max_length>40</max_length>
- <hint>Include none</hint>
- </column>
- <column>
- <name>default_value</name>
- <type>string</type>
- <label>Default value</label>
- <max_length>512</max_length>
- <hint>Default value</hint>
- </column>
- <column>
- <name>question_text</name>
- <type>translated_field</type>
- <label>Question text</label>
- <max_length>255</max_length>
- <hint>Question text</hint>
- </column>
- <column>
- <name>mandatory</name>
- <type>boolean</type>
- <label>Mandatory</label>
- <max_length>40</max_length>
- <hint>Mandatory</hint>
- </column>
- <column>
- <name>list_table</name>
- <type>list_table</type>
- <label>List table</label>
- <max_length>80</max_length>
- <hint>List table</hint>
- </column>
- <column>
- <name>attributes</name>
- <type>string</type>
- <label>Variable attributes</label>
- <max_length>255</max_length>
- <hint>Variable attributes</hint>
- </column>
- <column>
- <name>lookup_table</name>
- <type>table_name</type>
- <label>Lookup from table</label>
- <max_length>80</max_length>
- <hint>Lookup from table</hint>
- </column>
- <column>
- <name>lookup_value</name>
- <type>field_name</type>
- <label>Lookup value field</label>
- <max_length>80</max_length>
- <hint>Lookup value field</hint>
- </column>
- <column>
- <name>reference_qual</name>
- <type>string</type>
- <label>Reference qual</label>
- <max_length>255</max_length>
- <hint>Reference qual</hint>
- </column>
- </dictionary_entries>
- </table>
- <table>
- <name>x_ausgh_snsc_sara_lookup_ist</name>
- <label>Sara Lookup ImportSet</label>
- <extends_table>sys_import_set_row</extends_table>
- <user_role>catalog</user_role>
- <is_extendable>false</is_extendable>
- <dictionary_entries>
- <column>
- <name>u_key</name>
- <type>string</type>
- <label>Key</label>
- <max_length>203</max_length>
- <hint>The key value of lookup value</hint>
- <mandatory>true</mandatory>
- <display>true</display>
- </column>
- <column>
- <name>u_display_name</name>
- <type>string</type>
- <label>Display Name</label>
- <display>true</display>
- <max_length>1023</max_length>
- <hint>The display name value of lookup value</hint>
- </column>
- <column>
- <name>u_control_id</name>
- <type>string</type>
- <label>Lookup Control ID</label>
- <max_length>32</max_length>
- <hint>The sys_id of control which owns this lookup value</hint>
- </column>
- </dictionary_entries>
- </table>
- </tables>
- <transform_maps>
- <transform_map>
- <name>x_ausgh_snsc_sc_catalog_transform_map</name>
- <source_table>x_ausgh_snsc_sc_catalog_ist</source_table>
- <target_table>sc_catalog</target_table>
- <copy_empty_fields>true</copy_empty_fields>
- <active>true</active>
- <run_business_rules>false</run_business_rules>
- <fields>
- <field>
- <source_field>title</source_field>
- <coalesce>true</coalesce>
- </field>
- <field>
- <source_field>active</source_field>
- </field>
- <field>
- <source_field>description</source_field>
- </field>
- </fields>
- </transform_map>
- <transform_map>
- <name>x_ausgh_snsc_sc_category_transform_map</name>
- <source_table>x_ausgh_snsc_sc_category_ist</source_table>
- <target_table>sc_category</target_table>
- <copy_empty_fields>true</copy_empty_fields>
- <active>true</active>
- <run_business_rules>false</run_business_rules>
- <fields>
- <field>
- <source_field>title</source_field>
- <coalesce>true</coalesce>
- </field>
- <field>
- <source_field>homepage_renderer</source_field>
- </field>
- <field>
- <source_field>active</source_field>
- </field>
- <field>
- <source_field>description</source_field>
- </field>
- <field>
- <source_field>parent</source_field>
- <coalesce>true</coalesce>
- <reference_value_field>sys_id</reference_value_field>
- <copy_empty_fields>true</copy_empty_fields>
- <choice_action>reject</choice_action>
- </field>
- <field>
- <source_field>sc_catalog</source_field>
- </field>
- </fields>
- </transform_map>
- <transform_map>
- <name>x_ausgh_snsc_sc_cat_item_transform_map</name>
- <source_table>x_ausgh_snsc_sc_cat_item_ist</source_table>
- <target_table>sc_cat_item</target_table>
- <active>true</active>
- <run_business_rules>false</run_business_rules>
- <copy_empty_fields>true</copy_empty_fields>
- <fields>
- <field>
- <source_field>name</source_field>
- <coalesce>true</coalesce>
- </field>
- <field>
- <source_field>category</source_field>
- <coalesce>true</coalesce>
- <choice_action>reject</choice_action>
- <reference_value_field>sys_id</reference_value_field>
- </field>
- <field>
- <source_field>active</source_field>
- </field>
- <field>
- <source_field>short_description</source_field>
- </field>
- <field>
- <source_field>description</source_field>
- </field>
- <field>
- <source_field>custom_cart</source_field>
- <reference_value_field>sys_id</reference_value_field>
- <choice_action>reject</choice_action>
- </field>
- <field>
- <source_field>use_sc_layout</source_field>
- </field>
- <field>
- <source_field>no_quantity</source_field>
- </field>
- </fields>
- </transform_map>
- <transform_map>
- <name>x_ausgh_snsc_item_option_new_set_transform_map</name>
- <source_table>x_ausgh_snsc_item_option_new_set_ist</source_table>
- <target_table>item_option_new_set</target_table>
- <active>true</active>
- <run_business_rules>false</run_business_rules>
- <copy_empty_fields>true</copy_empty_fields>
- <fields>
- <field>
- <source_field>name</source_field>
- <coalesce>true</coalesce>
- </field>
- <field>
- <source_field>description</source_field>
- </field>
- <field>
- <source_field>title</source_field>
- </field>
- <field>
- <source_field>sys_name</source_field>
- </field>
- </fields>
- </transform_map>
- <transform_map>
- <name>x_ausgh_snsc_io_set_item_transform_map</name>
- <source_table>x_ausgh_snsc_io_set_item_ist</source_table>
- <target_table>io_set_item</target_table>
- <active>true</active>
- <run_business_rules>false</run_business_rules>
- <copy_empty_fields>true</copy_empty_fields>
- <fields>
- <field>
- <source_field>sc_cat_item</source_field>
- <coalesce>true</coalesce>
- <reference_value_field>sys_id</reference_value_field>
- <choice_action>reject</choice_action>
- </field>
- <field>
- <source_field>variable_set</source_field>
- <coalesce>true</coalesce>
- <reference_value_field>sys_id</reference_value_field>
- <choice_action>reject</choice_action>
- </field>
- </fields>
- </transform_map>
- <transform_map>
- <name>x_ausgh_snsc_sara_definition_transform_map</name>
- <source_table>x_ausgh_snsc_sara_definition_ist</source_table>
- <target_table>x_ausgh_snsc_sara_definition</target_table>
- <active>true</active>
- <run_business_rules>false</run_business_rules>
- <copy_empty_fields>true</copy_empty_fields>
- <fields>
- <field>
- <source_field>u_name</source_field>
- <coalesce>true</coalesce>
- </field>
- <field>
- <source_field>u_consume_url</source_field>
- </field>
- <field>
- <source_field>u_sc_item</source_field>
- </field>
- <field>
- <source_field>u_service_catalog_category</source_field>
- <reference_value_field>sys_id</reference_value_field>
- <choice_action>reject</choice_action>
- </field>
- <field>
- <source_field>u_var_set</source_field>
- <reference_value_field>sys_id</reference_value_field>
- <choice_action>reject</choice_action>
- </field>
- <field>
- <source_field>u_parent</source_field>
- <coalesce>true</coalesce>
- <reference_value_field>sys_id</reference_value_field>
- <choice_action>ignore</choice_action>
- </field>
- <field>
- <source_field>u_type</source_field>
- </field>
- <field>
- <source_field>u_hash</source_field>
- </field>
- </fields>
- </transform_map>
- <transform_map>
- <name>x_ausgh_snsc_sara_variable_transform_map</name>
- <source_table>x_ausgh_snsc_sara_variable_ist</source_table>
- <target_table>x_ausgh_snsc_sara_variable</target_table>
- <active>true</active>
- <run_business_rules>false</run_business_rules>
- <copy_empty_fields>true</copy_empty_fields>
- <fields>
- <field>
- <source_field>u_name</source_field>
- <coalesce>true</coalesce>
- </field>
- <field>
- <source_field>u_readonly</source_field>
- </field>
- <field>
- <source_field>u_is_password</source_field>
- </field>
- <field>
- <source_field>u_is_lookup</source_field>
- </field>
- <field>
- <source_field>u_hash</source_field>
- </field>
- <field>
- <source_field>variable_set</source_field>
- <reference_value_field>name</reference_value_field>
- <choice_action>reject</choice_action>
- </field>
- <field>
- <source_field>type</source_field>
- </field>
- <field>
- <source_field>macro</source_field>
- </field>
- <field>
- <source_field>name</source_field>
- </field>
- <field>
- <source_field>cat_item</source_field>
- <reference_value_field>sys_id</reference_value_field>
- <choice_action>reject</choice_action>
- </field>
- <field>
- <source_field>help_text</source_field>
- </field>
- <field>
- <source_field>show_help</source_field>
- </field>
- <field>
- <source_field>include_none</source_field>
- </field>
- <field>
- <source_field>default_value</source_field>
- </field>
- <field>
- <source_field>question_text</source_field>
- </field>
- <field>
- <source_field>mandatory</source_field>
- </field>
- <field>
- <source_field>list_table</source_field>
- </field>
- <field>
- <source_field>attributes</source_field>
- </field>
- <field>
- <source_field>lookup_table</source_field>
- </field>
- <field>
- <source_field>lookup_value</source_field>
- </field>
- <field>
- <source_field>reference_qual</source_field>
- </field>
- </fields>
- </transform_map>
- <transform_map>
- <name>x_ausgh_snsc_sara_lookup_transform_map</name>
- <source_table>x_ausgh_snsc_sara_lookup_ist</source_table>
- <target_table>x_ausgh_snsc_sara_lookup</target_table>
- <active>true</active>
- <run_business_rules>false</run_business_rules>
- <copy_empty_fields>true</copy_empty_fields>
- <fields>
- <field>
- <source_field>u_key</source_field>
- <coalesce>true</coalesce>
- </field>
- <field>
- <source_field>u_display_name</source_field>
- </field>
- <field>
- <source_field>u_control_id</source_field>
- <coalesce>true</coalesce>
- <reference_value_field>sys_id</reference_value_field>
- <choice_action>ignore</choice_action>
- </field>
- </fields>
- </transform_map>
- </transform_maps>
- <script_includes>
- <script_include>
- <name>SaraCatalogGenerator</name>
- <script><![CDATA[/**
- * Service Catalog Generator to import service definition to Service Catalog
- */
- var SaraCatalogGenerator = Class.create();
- SaraCatalogGenerator.prototype = {
- initialize: function () {
- this.glideHelper = new SaraGlideHelper();
- this.LOGGER = new SaraLog(this);
- },
- /**
- * Save catalog item
- * @param {SaraModel.CatalogItem} catalogItem The catalog item object
- */
- saveItem: function (catalogItem) {
- var LOGGER = this.LOGGER;
- LOGGER.info('Saving catalog item (name = "{0}", service name = {1}) in "{2}" table', catalogItem.getName(), catalogItem.getServiceName(), SaraCommon.TABLE_NAME.SARA_DEFINITION);
- var glideHelper = this.glideHelper;
- // Workflow sys_id of catalogItem if has
- var workflowSysId;
- if (catalogItem.getWorkflow()) {
- workflowSysId = glideHelper.getSysId(SaraCommon.TABLE_NAME.SN_WORKFLOW, {
- 'name': catalogItem.getWorkflow()
- });
- } else {
- LOGGER.error('There is no Workflow for consuming catalog item. Saving catalog item is aborted!');
- return;
- }
- // Custom cart sys_id of catalogItem if has
- var customCartSysId;
- if (catalogItem.getCustomCart()) {
- customCartSysId = glideHelper.getSysId(SaraCommon.TABLE_NAME.SN_UI_MACRO, {
- 'name': catalogItem.getCustomCart()
- });
- }
- var catalogItemId = glideHelper.persistData(SaraCommon.TABLE_NAME.SN_CATALOG_ITEM, {
- 'name': catalogItem.getName(),
- 'category': catalogItem.getCategory(),
- 'active': catalogItem.isActive(),
- 'short_description': catalogItem.getShortDesc(),
- 'description': catalogItem.getDescription(),
- 'workflow': workflowSysId,
- 'custom_cart': customCartSysId,
- 'use_sc_layout': false,
- 'no_quantity': true
- });
- var varSetId = this.saveVariableSet(catalogItem, catalogItemId);
- // Add new row to SaraCommon.TABLE_NAME.SARA_DEFINITION table, holding additional info. about this services like consume URL, links
- // and reference to the variable set that contains Sara fields
- var catItemId = glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_sc_item': catalogItemId,
- 'u_name': catalogItem.getServiceName(),
- 'u_consume_url': catalogItem.getConsumeUrl(),
- 'u_var_set': varSetId,
- 'u_parent': catalogItem.getCategory(),
- 'u_type': 'service',
- 'u_hash': catalogItem.getHash(),
- 'u_is_deleted': false
- });
- LOGGER.info('Saved catalog item (name = "{0}", service name = {1}, sys_id = {2}) in "{3}" table', catalogItem.getName(), catalogItem.getServiceName(), catItemId, SaraCommon.TABLE_NAME.SARA_DEFINITION);
- },
- /**
- * Create Sara Client Scripts with type is Macro and using UI Macro name SaraCommon.CONTROL_NAME.CLIENT_SCRIPTS. This control help us to
- * include all SNSC client scripts
- * @param {String} varSetId The sys_id of variable set
- */
- createSaraClientScripts: function (varSetId) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- var macroSaraClientScripts = glideHelper.getData(SaraCommon.TABLE_NAME.SN_UI_MACRO, {
- 'name': SaraCommon.CONTROL_NAME.CLIENT_SCRIPTS
- });
- if (macroSaraClientScripts) {
- var sysId = glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_VARIABLE, {
- 'name': SaraCommon.CONTROL_NAME.CLIENT_SCRIPTS,
- 'type': SaraCommon.VAR_TYPE.MACRO,
- 'u_is_lookup': false,
- 'macro': macroSaraClientScripts['sys_id'],
- 'variable_set': varSetId
- });
- LOGGER.info('Created client scripts (sys_id = {0}) for variable set (sys_id = {1})', sysId, varSetId);
- } else {
- LOGGER.info('There\' no UI Macro named "{0}". Creating Sara client scripts skipped!', SaraCommon.CONTROL_NAME.CLIENT_SCRIPTS);
- }
- },
- /**
- * Create Sara Hidden Variable with type is Macro and using UI Macro name SaraCommon.CONTROL_NAME.HIDDEN_CONTROL. This control help us
- * to run x_ausgh_snsc.SaraVarSet.onLoad() method without creating Catalog Client Script for VariableSet
- * @param {String} varSetId The sys_id of variable set
- */
- createSaraHiddenVariable: function (varSetId) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- var macroSaraHiddenControl = glideHelper.getData(SaraCommon.TABLE_NAME.SN_UI_MACRO, {
- 'name': SaraCommon.CONTROL_NAME.HIDDEN_CONTROL
- });
- if (macroSaraHiddenControl) {
- var sysId = glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_VARIABLE, {
- 'name': SaraCommon.CONTROL_NAME.HIDDEN_CONTROL,
- 'type': SaraCommon.VAR_TYPE.MACRO,
- 'u_is_lookup': false,
- 'macro': macroSaraHiddenControl['sys_id'],
- 'variable_set': varSetId
- });
- LOGGER.info('Created hidden variable (sys_id = {0}) for variable set (sys_id = {1})', sysId, varSetId);
- } else {
- LOGGER.info('There\' no UI Macro named "{0}". Creating Sara hidden control skipped!', SaraCommon.CONTROL_NAME.HIDDEN_CONTROL);
- }
- },
- /**
- * Save variable
- * @param {SaraModel.CatalogVariable} variable
- * @param {String} catalogItemId
- * @param {String} varSetId
- * @param {Object} optionals
- * @return {String} sys_id of saved variable
- */
- saveVariable: function (variable, catalogItemId, varSetId, optionals) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- LOGGER.info('Saving variable (name = {0}, type = {1}, isLookup = {2})...', variable.getName(), variable.getType(), variable.isLookup());
- var variableData = {
- 'name': variable.getName(),
- 'type': variable.getType(),
- 'u_is_lookup': variable.isLookup(),
- 'u_hash': variable.getHash()
- };
- if (catalogItemId) {
- variableData['cat_item'] = catalogItemId;
- } else if (varSetId) {
- variableData['variable_set'] = varSetId;
- }
- if (variable.getDescription()) {
- variableData['help_text'] = variable.getDescription();
- variableData['show_help'] = true;
- }
- // Include '-- None --' option if type is 'LOOKUP_SELECT_BOX' and there's no defaultValue
- if (variable.getType() === SaraCommon.VAR_TYPE.LOOKUP_SELECT_BOX && (!variable.getDefaultValue() || !variable.getDefaultValue()[0])) {
- variableData['include_none'] = true;
- }
- // Add default value if have and default value is not array
- if (variable.getDefaultValue() && variable.getDefaultValue().length === 1 && variable.getType() !== SaraCommon.VAR_TYPE.LIST_COLLECTOR) {
- variableData['default_value'] = variable.getDefaultValue()[0];
- }
- variableData['question_text'] = variable.getLabel();
- variableData['mandatory'] = variable.isRequired();
- if (optionals) {
- for (prop in optionals) {
- variableData[prop] = optionals[prop];
- }
- }
- // Additional fields for Sara
- variableData['u_name'] = variable.getActualName();
- variableData['u_is_password'] = variable.isPassword();
- // get 'catalog' user role
- var catalogRoleId = glideHelper.getSysId(SaraCommon.TABLE_NAME.SN_ROLE, {
- 'name': 'catalog'
- });
- LOGGER.debug('Variable information: {0}', SaraJSON.stringify(variableData));
- // Save variable to SaraCommon.TABLE_NAME.SARA_VARIABLE table
- var variableId = glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_VARIABLE, variableData);
- // Process variable range for all lookup controls
- if (variable.isLookup()) {
- LOGGER.info('Saving lookup table for lookup control (sys_id = {0})...', variableId);
- // Default value for list collector is list of value id in range table
- var defaultValueForListCollector = [];
- // Update data for lookup controls
- var updateData = {};
- var ranges = variable.getRange();
- if (ranges) {
- // Insert values to lookup table
- for (var i = 0, rangeValue; rangeValue = variable.range[i]; i++) {
- var rangeId = glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_LOOKUP, {
- 'u_key': rangeValue.Value,
- 'u_display_name': rangeValue.Key,
- 'u_control_id': variableId
- });
- if (SaraUtils.inArray(variable.defaultValue, rangeValue.Key)) {
- defaultValueForListCollector.push(rangeId);
- }
- }
- LOGGER.info('Insert {0} values to table "{1}" finished successfully.', ranges.length, SaraCommon.TABLE_NAME.SARA_LOOKUP);
- } else {
- LOGGER.info('Lookup values of {0} is null', variable.getName());
- }
- if (variable.getType() === SaraCommon.VAR_TYPE.LIST_COLLECTOR) {
- updateData['list_table'] = SaraCommon.TABLE_NAME.SARA_LOOKUP;
- updateData['default_value'] = defaultValueForListCollector.join(',');
- updateData['attributes'] = 'no_filter=true';
- } else {
- updateData['lookup_table'] = SaraCommon.TABLE_NAME.SARA_LOOKUP;
- updateData['lookup_value'] = 'u_display_name';
- updateData['reference_qual'] = 'u_control_id=' + variableId;
- }
- LOGGER.debug('Variable updated information: {0}', SaraJSON.stringify(updateData));
- glideHelper.updateData(SaraCommon.TABLE_NAME.SARA_VARIABLE, {
- 'sys_id': variableId
- }, updateData);
- LOGGER.info('Saved lookup table for lookup control (sys_id = {0})', variableId);
- }
- LOGGER.info('Saved variable (name = {0}, type = {1}, isLookup = {2})', variable.getName(), variable.getType(), variable.isLookup());
- return variableId;
- },
- /**
- * Delete variable
- * @param {String} variableId The sys_id of variable
- */
- deleteVariable: function (variableId) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- LOGGER.debug('Deleting lookup value of variable (sys_id = {0})...', variableId);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_LOOKUP, {
- 'u_control_id': variableId
- }, true);
- LOGGER.debug('Deleted lookup value of variable (sys_id = {0})', variableId);
- LOGGER.debug('Deleting variable (sys_id = {0})...', variableId);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_VARIABLE, {
- 'sys_id': variableId
- }, true);
- LOGGER.debug('Deleted variable (sys_id = {0})', variableId);
- },
- /**
- * Delete all variables of a variable set
- * @param {String} varSetId The sys_id of variable set
- */
- deleteVariables: function (varSetId) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- var saraVariables = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_VARIABLE, {
- 'variable_set': varSetId
- }, true);
- LOGGER.info('Found {0} variable(s) of variable set (sys_id = {1})', saraVariables.length, varSetId);
- LOGGER.info('Starting delete all vairables and their lookup value...');
- for (var i = 0, saraVariable; saraVariable = saraVariables[i]; i++) {
- this.deleteVariable(saraVariable['sys_id']);
- }
- LOGGER.info('Ended delete all vairables and their lookup value');
- },
- /**
- * Create catalog category
- * @param {SaraModel.CatalogCategory} catalogCategory
- * @return {String} Category ID from table SaraCommon.TABLE_NAME.SN_CATEGORY
- */
- saveCategory: function (catalogCategory) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- // Assign default homepage renderer
- var defaultRendererSysId = glideHelper.getSysId(SaraCommon.TABLE_NAME.SN_HOMEPAGE_RENDERER, {
- 'Name': 'Category Items'
- });
- // Create catalog category without specified 'parent' because of 'PreventSubcategoryCatalogChange' business rule of Eureka
- LOGGER.info('Creating Catalog category {0} (sys_id = {1})...', catalogCategory.getName(), catalogCatId);
- var catalogCatId = glideHelper.persistData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'title': catalogCategory.getTitle(),
- 'homepage_renderer': defaultRendererSysId,
- 'active': catalogCategory.isActive(),
- 'description': catalogCategory.getDescription()
- });
- LOGGER.info('Created Catalog category {0} (sys_id = {1})', catalogCategory.getName(), catalogCatId);
- // Update 'parent' for catalog category after creating successfully
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': catalogCatId
- }, {
- 'parent': catalogCategory.getParent()
- }, true);
- // Add new row to SaraCommon.TABLE_NAME.SARA_DEFINITION table, holding additional info. about this category
- LOGGER.info('Saving Catalog category {0} (sys_id = {1}) into "{2}" table...', catalogCategory.getName(), catalogCatId, SaraCommon.TABLE_NAME.SARA_DEFINITION);
- glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_service_catalog_category': catalogCatId,
- 'u_name': catalogCategory.getName(),
- 'u_consume_url': catalogCategory.getConsumeUrl() || '',
- 'u_parent': catalogCategory.getParent(),
- 'u_type': 'catalog'
- });
- LOGGER.info('Saved Catalog category {0} (sys_id = {1}) into "{2}" table', catalogCategory.getName(), catalogCatId, SaraCommon.TABLE_NAME.SARA_DEFINITION);
- return catalogCatId;
- },
- /**
- * Create default target category named 'SaraCommon.DEFAULT_CATEGORY'
- * @param {String} catalogCatId The catalog category sys_id
- * @return {String} sysId
- */
- createDefaultTargetCategory: function (catalogCateId) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- var defaultCategoryName = SaraCommon.DEFAULT_CATEGORY;
- LOGGER.info('Saving category (name = {0})', defaultCategoryName);
- var entity = {
- 'title': defaultCategoryName,
- 'active': true,
- 'description': defaultCategoryName,
- }
- if (catalogCateId) {
- entity['sc_catalog'] = catalogCateId;
- }
- var sysId = glideHelper.persistData(SaraCommon.TABLE_NAME.SN_CATEGORY, entity);
- LOGGER.info('Saved category (name = {0})!', defaultCategoryName);
- return sysId;
- },
- /**
- * Save target category id into SaraCommon.TABLE_NAME.SARA_DEFINITION table
- * @param {String} targetCateId
- */
- saveTargetCategory: function (targetCateId) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- var targetCategory = glideHelper.getData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': targetCateId
- });
- var sysIdImportedCategory = glideHelper.getSysId(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_parent': targetCateId,
- 'u_type': 'category'
- });
- if (sysIdImportedCategory) {
- LOGGER.info('Services have been imported in target category (name = {0})!', targetCategory['title']);
- } else {
- sysIdImportedCategory = glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_name': targetCategory['title'],
- 'u_parent': targetCategory['sys_id'],
- 'u_type': 'category'
- });
- LOGGER.info('Saved target category (name = {0}, sys_id = {1}) into "{2}" table', targetCategory['title'], sysIdImportedCategory, SaraCommon.TABLE_NAME.SARA_DEFINITION);
- }
- },
- /**
- * Update catalog category
- * @param {SaraModel.CatalogCategory} catalog
- */
- updateCategory: function (catalogCategory) {
- if (!catalogCategory.getSysId()) {
- return;
- }
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- LOGGER.info('Updating catalog category (title = {0}, description = {1})...', catalogCategory['title'], catalogCategory['description']);
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': catalogCategory.getSysId()
- }, {
- 'title': catalogCategory.getTitle(),
- 'description': catalogCategory.getDescription()
- });
- LOGGER.info('Updated catalog category (title = {0}, description = {1})', catalogCategory['title'], catalogCategory['description']);
- },
- /**
- * Save variable set for catalog item
- * @param {SaraModel.CatalogItem} catalogItem The catalog item object
- * @param {String} catalogId The sys_id of catalog item in db
- * @return {String} The sys_id of variable set
- */
- saveVariableSet: function (catalogItem, catalogId) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- var varSetId = null;
- // Process catalog variables
- if (catalogItem.variables.length > 0) {
- var varSetName = SaraUtils.formatString('VarSet_{0}_{1}', SaraUtils.getTimeStamp(), SaraUtils.getRandom());
- // Create a variable set containing all variables and save variable set to SaraCommon.TABLE_NAME.SN_VARIABLE_SET table
- LOGGER.info('Saving variable set (name = {0})...', varSetName);
- varSetId = glideHelper.persistData(SaraCommon.TABLE_NAME.SN_VARIABLE_SET, {
- 'name': varSetName,
- 'description': SaraUtils.formatString('Variable Set containing all variables belong to "{0}" ({1}) catalog item', catalogItem.getName(), catalogItem.getServiceName()),
- 'title': SaraUtils.formatString('{0} Variable Set', catalogItem.getName()),
- 'display_title': true
- });
- LOGGER.info('Saved variable set (name = {0})', varSetName);
- // Create relation between variable set and catalog item by adding a record to SaraCommon.TABLE_NAME.SN_VARIABLE_SET_ITEM table
- LOGGER.info('Creating relation between variable set (name = {0}, sys_id = {1}) and catalog item (sys_id = {2})...', varSetName, varSetId, catalogId);
- glideHelper.persistData(SaraCommon.TABLE_NAME.SN_VARIABLE_SET_ITEM, {
- 'sc_cat_item': catalogId,
- 'variable_set': varSetId
- });
- LOGGER.info('Created relation between variable set (name = {0}, sys_id = {1}) and catalog item (sys_id = {2})', varSetName, varSetId, catalogId);
- // Creating Sara client scripts
- this.createSaraClientScripts(varSetId);
- // Creating Sara hidden variable
- this.createSaraHiddenVariable(varSetId);
- // process each variable in the set
- LOGGER.info('Importing {0} variables for variable set named "{1}"...', catalogItem.variables.length, varSetName);
- for (var i = 0, variable; variable = catalogItem.variables[i]; i++) {
- this.saveVariable(variable, null, varSetId, {
- 'order': (i * 100)
- });
- }
- LOGGER.info('Imported {0} variables for variable set (name = {1}, sys_id = {2})', catalogItem.variables.length, varSetName, varSetId);
- } else {
- LOGGER.warn('There\' no variable found in catalog item (name = {0}). Skip syncLookup!', catalogItem.getName());
- }
- return varSetId;
- },
- /**
- * Delete variable set for catalog item
- * @param {Object} saraItem The current catalog item in db
- * @param {SaraModel.CatalogItem} catalogItem The catalog item object
- */
- deleteVariableSet: function (saraItem, catalogItem) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- LOGGER.info('Getting all variable set of catalog item (name = {0}, sys_id = {1})...', catalogItem.getServiceName(), saraItem['u_sc_item']);
- var setItems = glideHelper.getData(SaraCommon.TABLE_NAME.SN_VARIABLE_SET_ITEM, {
- 'sc_cat_item': saraItem['u_sc_item']
- }, true);
- LOGGER.info('Got {0} variable set(s) of catalog item (name = {1}, sys_id = {2})', setItems.length, catalogItem.getServiceName(), saraItem['u_sc_item']);
- for (var i = 0, setItem; setItem = setItems[i]; i++) {
- this.deleteVariables(setItem['variable_set']);
- LOGGER.info('Deleting variable set (sys_id = {0}) of catalog item (name = {1}, sys_id = {2})...', setItem['variable_set'], catalogItem.getServiceName(), saraItem['u_sc_item']);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SN_VARIABLE_SET, {
- 'sys_id': setItem['variable_set']
- });
- LOGGER.info('Deleted variable set (sys_id = {0}) of catalog item (name = {1}, sys_id = {2})', setItem['variable_set'], catalogItem.getServiceName(), saraItem['u_sc_item']);
- }
- // Delete relation between all variable sets and catalog item by adding a record to SaraCommon.TABLE_NAME.SN_VARIABLE_SET_ITEM table
- LOGGER.info('Deleting relation between catalog item (name = {0}, sys_id = {1}) with all variable sets...', catalogItem.getServiceName(), saraItem['u_sc_item']);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SN_VARIABLE_SET_ITEM, {
- 'sc_cat_item': saraItem['u_sc_item']
- }, true);
- LOGGER.info('Deleted relation between catalog item (name = {0}, sys_id = {1}) with all variable sets', catalogItem.getServiceName(), saraItem['u_sc_item']);
- },
- /**
- * Update catalog item
- * @param {Object} saraItem The current catalog item in db
- * @param {SaraModel.CatalogItem} catalogItem The catalog item object
- */
- updateItem: function (saraItem, catalogItem) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- LOGGER.info('Updating catalog item (name = "{0}", sys_id = {1})...', catalogItem.getServiceName(), saraItem['u_sc_item']);
- this.deleteVariableSet(saraItem, catalogItem);
- var varSetId = this.saveVariableSet(catalogItem, saraItem['u_sc_item']);
- LOGGER.info('Saving new variable set (sys_id = {0}) and hash ({1}) for catalog item in "{2}" table...', saraItem['sys_id'], catalogItem.getHash(), SaraCommon.TABLE_NAME.SARA_DEFINITION);
- glideHelper.updateData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'sys_id': saraItem['sys_id']
- }, {
- 'u_var_set': varSetId,
- 'u_hash': catalogItem.getHash()
- });
- LOGGER.info('Saved new variable set (sys_id = {0}) and hash ({1}) for catalog item in "{2}" table', saraItem['sys_id'], catalogItem.getHash(), SaraCommon.TABLE_NAME.SARA_DEFINITION);
- LOGGER.info('Updated catalog item (name = "{0}", sys_id = {1})', catalogItem.getServiceName(), saraItem['u_sc_item']);
- },
- /**
- * Set active status of item in SaraCommon.TABLE_NAME.SN_CATALOG_ITEM table
- * @param {Object} saraItem The catalog item which will be set active status
- * @param {Boolean} isActive The catalog item is active or not
- */
- setItemActive: function (saraItem, isActive) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- // Deactive item in SaraCommon.TABLE_NAME.SN_CATALOG_ITEM table
- LOGGER.info('Setting active status of catalog item (sys_id = {0}) is "{1}" in table "{2}"...', saraItem['u_sc_item'], isActive, SaraCommon.TABLE_NAME.SN_CATALOG_ITEM);
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATALOG_ITEM, {
- 'sys_id': saraItem['u_sc_item']
- }, {
- 'active': isActive
- });
- LOGGER.info('Set active status of catalog item (sys_id = {0}) is "{1}" in table "{2}"', saraItem['u_sc_item'], isActive, SaraCommon.TABLE_NAME.SN_CATALOG_ITEM);
- },
- /**
- * Deactivate item and also remove its information out of SaraCommon.TABLE_NAME.SARA_DEFINITION
- * @param {Object} saraItem The catalog item which will be deactivated and marked as deleted
- * @param {Object} saraCatalog The old catalog data from SaraCommon.TABLE_NAME.SARA_DEFINITION table
- */
- deleteItem: function (saraItem, saraCatalog) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- this.setItemActive(saraItem, false);
- LOGGER.info('Deactivated catalog item (sys_id = {0}) in table "{1}"', saraItem['u_sc_item'], SaraCommon.TABLE_NAME.SN_CATALOG_ITEM);
- // Mark catalog item as deleted in SaraCommon.TABLE_NAME.SN_CATALOG_ITEM table
- LOGGER.info('Marking catalog item as deleted (sys_id = {0}) in table "{1}"', saraItem['u_sc_item'], SaraCommon.TABLE_NAME.SN_CATALOG_ITEM);
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATALOG_ITEM, {
- 'sys_id': saraItem['u_sc_item']
- }, {
- 'meta': 'deleted'
- });
- LOGGER.info('Marked catalog item as deleted (sys_id = {0}) in table "{1}"', saraItem['u_sc_item'], SaraCommon.TABLE_NAME.SN_CATALOG_ITEM);
- // Remove item's information in SaraCommon.TABLE_NAME.SARA_DEFINITION table
- LOGGER.info('Deleting catalog item (name = {0}, parent sys_id = {1}) in table "{2}"', saraItem['u_name'], saraItem['u_parent'], SaraCommon.TABLE_NAME.SARA_DEFINITION);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_name': saraItem['u_name'],
- 'u_parent': saraItem['u_parent'],
- 'u_type': 'service'
- }, true);
- LOGGER.info('Deleted catalog item (name = {0}, parent sys_id = {1}) successfully', saraItem['u_name'], saraCatalog['sys_id']);
- },
- /**
- * Deactivate category and also remove its information out of SaraCommon.TABLE_NAME.SARA_DEFINITION
- * @param {Object} saraCatalog The old catalog data from SaraCommon.TABLE_NAME.SARA_DEFINITION table
- */
- deactivateCategory: function (saraCatalog) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- // Deactive items which have parent is this category
- var items = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_parent': saraCatalog['u_service_catalog_category'],
- 'u_type': 'service'
- }, true);
- for (var i = 0, saraItem; saraItem = items[i]; i++) {
- this.deleteItem(saraItem, saraCatalog);
- }
- // Deactive category in 'SaraCommon.TABLE_NAME.SN_CATEGORY' table
- LOGGER.info('Deactivating category (sys_id = {0}) in table "{1}"...', saraCatalog['u_service_catalog_category'], SaraCommon.TABLE_NAME.SN_CATEGORY);
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': saraCatalog['u_service_catalog_category']
- }, {
- 'active': false
- })
- LOGGER.info('Deactivated category (sys_id = {0}) in table "{1}"', saraCatalog['u_service_catalog_category'], SaraCommon.TABLE_NAME.SN_CATEGORY);;
- // Remove category's information in SaraCommon.TABLE_NAME.SARA_DEFINITION table
- LOGGER.info('Deleting category (name = {0}, parent sys_id = {1}) in table "{2}"...', saraCatalog['u_name'], saraCatalog['u_parent'], SaraCommon.TABLE_NAME.SARA_DEFINITION);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_name': saraCatalog['u_name'],
- 'u_parent': saraCatalog['u_parent'],
- 'u_type': 'catalog'
- }, true);
- LOGGER.info('Deleted category (name = {0}, parent sys_id = {1}) in table "{2}"', saraCatalog['u_name'], saraCatalog['u_parent'], SaraCommon.TABLE_NAME.SARA_DEFINITION);
- },
- /**
- * Creates a new catalog
- */
- createCatalog: function (title, description, active) {
- return this.glideHelper.persistData(SaraCommon.TABLE_NAME.SN_CATALOG, {
- 'title': title,
- 'description': description,
- 'active': active
- });
- },
- type: 'SaraCatalogGenerator'
- };
- ]]></script>
- <description>Service Catalog Generator to import service definition to Service Catalog</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>package_private</access>
- </script_include>
- <script_include>
- <name>SaraCommon</name>
- <script><![CDATA[/**
- * This class is comprised of global parameters in SARA connector. It shouldn't be instantiated
- * and fields will be accessed in static-like fashion (think Java), eg.: SaraCommon.username
- */
- var SaraCommon = Class.create();
- SaraCommon.prototype = {
- initialize: function () {},
- type: 'SaraCommon'
- };
- SaraCommon.PROP_PREFIX = 'x_ausgh_snsc';
- SaraCommon.OAUTH_IMPORT_SUCCESS = 0;
- SaraCommon.OAUTH_AUTHENTICATION_FAILED = 1;
- SaraCommon.OAUTH_INVALID_TOKEN = 2;
- SaraCommon.OAUTH_TOKEN_EXPIRED = 3;
- SaraCommon.DEFAULT_CATEGORY = 'Automic Services';
- SaraCommon.CATALOGS_LIMIT = 1000;
- SaraCommon.SERVICES_LIMIT = 10;
- SaraCommon.WORKFLOW_STATUS_CODE = {
- ENDED_OK: 1900
- };
- SaraCommon.CUSTOM_CART_NAME = '';
- SaraCommon.VAR_TYPE = {
- YES_NO: 1,
- MULTI_LINE_TEXT: 2,
- MULTI_CHOICE: 3,
- NUM_SCALE: 4,
- SELECT_BOX: 5,
- SINGLE_LINE_TEXT: 6,
- CHECK_BOX: 7,
- REFERENCE: 8,
- DATE: 9,
- DATE_TIME: 10,
- LABEL: 11,
- BREAK: 12,
- MACRO: 14,
- UI_PAGE: 15,
- WIDE_SINGLE_LINE_TEXT: 16,
- MACRO_WITH_LABEL: 17,
- LOOKUP_SELECT_BOX: 18,
- CONTAINER_START: 19,
- CONTAINER_END: 20,
- LIST_COLLECTOR: 21,
- LOOKUP_MULTI_CHOICE: 22,
- HTML: 23
- };
- SaraCommon.CONTROL_NAME = {
- CLIENT_SCRIPTS: 'sara_client_scripts',
- HIDDEN_CONTROL: 'sara_hidden_control'
- };
- SaraCommon.SCOPED_APP = 'x_ausgh_snsc';
- SaraCommon.SYSTEM_PROPERTY_NAME = {
- MID_SERVER: 'mid_server',
- REST_REQUEST_TIMEOUT: 'rest_request_timeout',
- SERVICE_ACTIVE: 'service_active',
- WORKFLOW_TIMEOUT: 'workflow_timeout',
- WORKFLOW_DELAY: 'workflow_delay'
- };
- SaraCommon.CONFIG_NAME = {
- CLIENT_ID: 'client_id',
- CLIENT_SECRET: 'client_secret',
- TECHNICAL_USER: 'technical_user',
- SAPI_ENDPOINT: 'sapi_endpoint',
- TOKEN_ENDPOINT: 'token_endpoint',
- AUTH_ENDPOINT: 'auth_endpoint'
- };
- SaraCommon.REST_NAME = {
- SAPI: 'Sara - SAPI Services',
- OAUTH: 'Sara - OAuth Services'
- };
- // List of properties will be kept when syncing services
- SaraCommon.KEEP_SERIVCE_PROPERTIES = [];
- SaraCommon.TABLE_NAME = {
- SARA_CONFIG: 'x_ausgh_snsc_sara_config',
- SARA_DEFINITION: 'x_ausgh_snsc_sara_definition',
- SARA_INSTALL_LOG: 'u_snsc_install_log',
- SARA_LOOKUP: 'x_ausgh_snsc_sara_lookup',
- SARA_OAUTH: 'x_ausgh_snsc_sara_oauth',
- SARA_VARIABLE: 'x_ausgh_snsc_sara_variable',
- SN_APPLICATION: 'sys_app',
- SN_APPLICATION_CATEGORY: 'sys_app_category',
- SN_APPLICATION_FILE: 'sys_app_file',
- SN_APPLICATION_MENU: 'sys_app_application',
- SN_APPLICATION_MODULE: 'sys_app_module',
- SN_AUTO_SCRIPT: 'sysauto_script',
- SN_CATALOG: 'sc_catalog',
- SN_CATALOG_ITEM: 'sc_cat_item',
- SN_CATALOG_ITEM_WIZARD: 'sc_cat_item_wizard',
- SN_CATALOG_SCRIPT_CLIENT: 'catalog_script_client',
- SN_CATEGORY: 'sc_category',
- SN_DB_OBJECT: 'sys_db_object',
- SN_DICTIONARY: 'sys_dictionary',
- SN_DOCUMENTATION: 'sys_documentation',
- SN_ECC_QUEUE: 'ecc_queue',
- SN_FIX_SCRIPT: 'sys_script_fix',
- SN_HOMEPAGE_RENDERER: 'sc_homepage_renderer',
- SN_JOURNAL_FIELD: 'sys_journal_field',
- SN_METADATA: 'sys_metadata',
- SN_PROCESSOR: 'sys_processor',
- SN_PROPERTIES: 'sys_properties',
- SN_PROPERTIES_CATEGORY: 'sys_properties_category',
- SN_PROPERTIES_CATEGORY_RELATIONSHIP: 'sys_properties_category_m2m',
- SN_REST_MESSAGE: 'sys_rest_message',
- SN_REST_MESSAGE_FN: 'sys_rest_message_fn',
- SN_REST_MESSAGE_FN_HEADERS: 'sys_rest_message_fn_headers',
- SN_REST_MESSAGE_HEADERS: 'sys_rest_message_headers',
- SN_ROLE: 'sys_user_role',
- SN_SECURITY_ACL: 'sys_security_acl',
- SN_SECURITY_ACL_ROLE: 'sys_security_acl_role',
- SN_SCRIPT_INCLUDES: 'sys_script_include',
- SN_UI_MACRO: 'sys_ui_macro',
- SN_UI_PAGE: 'sys_ui_page',
- SN_UI_SCRIPT: 'sys_ui_script',
- SN_USER: 'sys_user',
- SN_USER_GROUP: 'sys_user_group',
- SN_VARIABLE: 'item_option_new',
- SN_VARIABLE_SET: 'item_option_new_set',
- SN_VARIABLE_SET_ITEM: 'io_set_item',
- SN_VARIABLE_VALUE: 'sys_variable_value',
- SN_WIZARD: 'expert',
- SN_WIZARD_CLIENT_SCRIPT: 'expert_script_client',
- SN_WIZARD_PANEL: 'expert_panel',
- SN_WIZARD_PANEL_TRANSITION: 'expert_panel_transition',
- SN_WIZARD_PANEL_VARIABLE: 'expert_panel_variable',
- SN_WIZARD_VARIABLE: 'expert_variable',
- SN_WORKFLOW: 'wf_workflow',
- SN_WORKFLOW_ACTIVITY: 'wf_activity',
- SN_WORKFLOW_ACTIVITY_DEFINITION: 'wf_activity_definition',
- SN_WORKFLOW_ACTIVITY_VARIABLE: 'wf_activity_variable',
- SN_WORKFLOW_CONDITION: 'wf_condition',
- SN_WORKFLOW_STAGE: 'wf_stage',
- SN_WORKFLOW_TRANSITION: 'wf_transition',
- SN_WORKFLOW_VERSION: 'wf_workflow_version',
- SN_TRANSFORM_MAP: 'sys_transform_map'
- };
- SaraCommon.AUDIT = {
- APPROVAL_HISTORY: 'SNSC_SN_APPROVAL_HISTORY',
- APPROVAL_TIMESTAMP: 'SNSC_SN_APPROVAL_TIMESTAMP',
- ORDER_ID : 'SNSC_SN_ORDER_ID',
- ORDER_NAME: 'SNSC_SN_ORDER_NAME',
- ORDER_TIMESTAMP: 'SNSC_SN_ORDER_TIMESTAMP'
- };
- ]]></script>
- <description>This class is comprised of global parameters in SARA connector. It shouldn't be instantiated and fields will be accessed in static-like fashion (think Java), eg.: SaraCommon.username</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraConfig</name>
- <script><![CDATA[/**
- * Helper class provides convenient methods to work with SNSC configuration table
- */
- var SaraConfig = Class.create();
- SaraConfig.prototype = {
- initialize: function () {
- this.glideHelper = new SaraGlideHelper();
- this.DEFAULT_CONFIG_VALUES = {};
- this.DEFAULT_CONFIG_VALUES[SaraCommon.CONFIG_NAME.CLIENT_ID] = 'AESYSTEMNAME/1/SERVICE_NOW';
- this.DEFAULT_CONFIG_VALUES[SaraCommon.CONFIG_NAME.CLIENT_SECRET] = 'AES_12345';
- this.DEFAULT_CONFIG_VALUES[SaraCommon.CONFIG_NAME.TECHNICAL_USER] = 'TECHNICAL_USER';
- this.DEFAULT_CONFIG_VALUES[SaraCommon.CONFIG_NAME.SAPI_ENDPOINT] = 'https://mysapihost/';
- this.DEFAULT_CONFIG_VALUES[SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT] = 'https://oauthhost/oauth2/token';
- this.DEFAULT_CONFIG_VALUES[SaraCommon.CONFIG_NAME.AUTH_ENDPOINT] = 'https://oauthhost/oauth2/auth';
- },
- /**
- * Store SARA OAuth client configuration to System Properties
- * @param {object} config The configuration of OAuth Client
- * - @key {String} SaraCommon.CONFIG_NAME.CLIENT_ID Identity of OAuth client
- * - @key {String} SaraCommon.CONFIG_NAME.CLIENT_SECRET OAuth client secret string
- * - @key {String} SaraCommon.CONFIG_NAME.TECHNICAL_USER Technical user
- * - @key {String} SaraCommon.CONFIG_NAME.SAPI_ENDPOINT URL to SAPI root endpoint
- * - @key {String} SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT Endpoint for token requesting/refreshing
- * - @key {String} SaraCommon.CONFIG_NAME.AUTH_ENDPOINT Authorization endpoint for OAuth authentication
- */
- storeClientConfig: function (config) {
- // Clean the old config before storing new one
- this.glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_CONFIG, {}, true);
- var configData = {};
- for (var key in config) {
- configData['u_' + key] = config[key];
- }
- // Store new config
- this.glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_CONFIG, configData);
- },
- /**
- * Get the object contains SARA client configuration in following order: Client ID, Client Secret, Technical User,
- * SAPI Endpoint, Token Endpoint, Authorization Endpoint
- * @return {Object}
- */
- getClientConfig: function () {
- var saraConfig = this.glideHelper.getData(SaraCommon.TABLE_NAME.SARA_CONFIG, {}, true)[0];
- var configData = {};
- if (saraConfig) {
- for (var key in SaraCommon.CONFIG_NAME) {
- var name = SaraCommon.CONFIG_NAME[key];
- configData[name] = saraConfig['u_' + name];
- }
- } else {
- configData = this.DEFAULT_CONFIG_VALUES;
- }
- return configData;
- },
- /**
- * Get base bath of SAPI endpoint
- * @return {String}
- */
- getBasePath: function () {
- var configData = this.getClientConfig();
- return configData[SaraCommon.CONFIG_NAME.SAPI_ENDPOINT];
- },
- /**
- * Get technical user name
- * @param {String}
- */
- getTechnicalUser: function () {
- var configData = this.getClientConfig();
- return configData[SaraCommon.CONFIG_NAME.TECHNICAL_USER];
- },
- type: 'SaraConfig'
- };
- ]]></script>
- <description>Helper class provides convenient methods to work with SNSC configuration table</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraConsumer</name>
- <script><![CDATA[/**
- * Sara consumer class to discover all SAPI catalogs, services and import them into SN as the corresponding catalog categories and items
- */
- var SaraConsumer = Class.create();
- SaraConsumer.prototype = {
- initialize: function (tracker) {
- if (tracker !== null && tracker !== undefined) {
- this.tracker = tracker;
- }
- // initialize dependencies
- var midServer = SaraUtils.getMIDServer();
- this.restClient = new SaraRESTClient();
- this.restClient.setMIDServer(midServer);
- this.username = new SaraConfig().getTechnicalUser();
- // inject restClient to the OAuth client instance
- this.oauthClient = new SaraOAuthClient(this.restClient);
- this.tokens = this.oauthClient.getUserTokens(this.username);
- // inject glideHelper
- this.glideHelper = new SaraGlideHelper();
- // Inject generator
- this.generator = new SaraCatalogGenerator();
- this.LOGGER = new SaraLog(this);
- /**
- * Object store catalogs data of SAPI after discovering
- * @structure:
- * {
- * @{catalogName}: @{SaraModel.CatalogCategory},
- * ...
- * }
- */
- this.catalogsData = {};
- /**
- * Object store services data of SAPI after discovering
- * @structure:
- * {
- * @{catalogName}: {
- * @{serviceName}: @{SaraModel.CatalogItem},
- * ...
- * },
- * ...
- * }
- */
- this.servicesData = {};
- // Object store catalogs and services number after discovering
- this.countData = {
- catalogsCount: 0,
- servicesCount: 0
- };
- this.statusCode = '';
- this.errorMessage = '';
- this.errorUrl = '';
- },
- getDefaultCategory: function () {
- return SaraCommon.DEFAULT_CATEGORY;
- },
- /**
- * Get link with limit parametter of catalog or service
- * @param {String} link Origin link
- * @param {String} type can be catalog or service
- * @param {String}
- */
- getLimitLink: function (link, type) {
- var limitString = 'limit=';
- limitString += type === 'catalog' ? SaraCommon.CATALOGS_LIMIT : SaraCommon.SERVICES_LIMIT;
- if (link.indexOf('?') !== -1) {
- limitString = '&' + limitString;
- } else {
- limitString = '?' + limitString;
- }
- return link + limitString;
- },
- /**
- * Private method to check user permission.
- * @return {Object}
- * - @key {String} error
- */
- checkPermission: function () {
- var LOGGER = this.LOGGER;
- if (!gs.hasRole('admin') && !gs.hasRole('groups_admin')) {
- var message = 'You dont\'t have sufficient permission to do this action. Allowed roles: admin, groups_admin';
- LOGGER.error(message);
- return {
- error: message
- }
- }
- // check user tokens
- if (!this.tokens) {
- var message = SaraUtils.formatString('No tokens found for user {0}. Skip import!', this.username);
- LOGGER.error(message);
- return {
- error: message
- }
- }
- LOGGER.info('Tokens found for user {0}', this.username);
- if (!this.tokens[3]) {
- this.tokens[3] = 'bearer';
- }
- return {
- error: false
- }
- },
- /**
- * Make request to SAPI and check the response data
- * @param {String} url
- * @param {Boolean} returnJSONData2
- * @return {Object}
- * - @key {Boolean} error
- * - @key {Object} response
- * - @key {Object} jsonData
- */
- makeSAPIRequest: function (url, returnJSONData2) {
- var LOGGER = this.LOGGER;
- // Make request
- this.tokens = this.oauthClient.getUserTokens(this.username);
- var requestUrl = SaraUtils.buildUrl(url);
- var request = this.restClient.newSAPIRequest('get', requestUrl);
- request.addHeader('Authorization', this.tokens[3] + ' ' + this.tokens[0]);
- // Get response
- var response = this.restClient.executeWithRefreshToken(request);
- var responseObject = response.getResponseObject();
- if (response.haveError()) {
- this.statusCode = responseObject.statusCode;
- this.errorMessage = responseObject.errorMessage;
- this.errorUrl = url;
- return {
- error: true,
- response: response
- };
- }
- var result = {
- error: false,
- response: response,
- jsonData: responseObject.bodyObject
- }
- if (returnJSONData2) {
- var jsonData2 = response.getBodyObject();
- result.jsonData2 = jsonData2;
- }
- return result;
- },
- /**
- * Increment specific percent more for tracker if have
- * @param {Number} percent
- */
- incrementPercent: function (percent) {
- if (this.tracker !== null) {
- this.tracker.incrementPercentComplete(+percent);
- }
- },
- /**
- * Log message for tracker can show what is happening inside of SaraConsumer when importing services.
- * You can format message like SaraUtils.formatString method
- */
- logMessage: function () {
- var LOGGER = this.LOGGER;
- if (this.tracker !== null) {
- var message = SaraUtils.formatString.apply(this, arguments);
- try {
- this.tracker.updateResult({
- msg: message
- });
- } catch (e) {
- LOGGER.error('Error when logging message for tracker: {0}', e);
- }
- }
- },
- /**
- * Discover root url of SAPI
- * @return {Object}
- * - @key {Boolean} error
- * - @key {Object} response
- * - @key {Object} jsonData
- */
- discoverRoot: function () {
- var LOGGER = this.LOGGER;
- LOGGER.info('Starting discoverRoot...');
- // Make request
- var response = this.makeSAPIRequest('/');
- if (response.error) {
- LOGGER.error(response.error);
- LOGGER.info('Ended discoverRoot!');
- return response;
- }
- LOGGER.info('Ended discoverRoot!');
- return response;
- },
- /**
- * Discover catalogs url of SAPI
- * @param {String} catalogsUrl
- * @return {Object}
- * - @key {Boolean} error
- * - @key {Object} response
- * - @key {Object} jsonData
- */
- discoverCatalogs: function (catalogsUrl) {
- var LOGGER = this.LOGGER;
- LOGGER.info('Starting discoverCatalogs...');
- // Set limit for catalogsUrl
- catalogsUrl = this.getLimitLink(catalogsUrl, 'catalog');
- // Make request
- var response = this.makeSAPIRequest(catalogsUrl);
- if (response.error) {
- LOGGER.error(response.error);
- LOGGER.info('Ended discoverCatalogs!');
- return response;
- }
- var jsonData = response.jsonData;
- this.countData.catalogsCount = jsonData['count'];
- LOGGER.info('Found {0} SAPI Catalogs, start discover each catalog.', jsonData['count']);
- LOGGER.info('Ended discoverCatalogs!');
- return response;
- },
- /**
- * Generate hash string of catalogItem. The hash will be generated from 'form' property
- * of catalogItem without 'range' property
- * @param {SaraModel.CatalogItem} catalogItemData
- * @return {String} hash
- */
- generateCatalogItemHash: function (catalogItemData) {
- for (var index in catalogItemData.forms) {
- var form = catalogItemData.forms[index];
- var fields = form.fields;
- for (var index2 in fields) {
- delete fields[index2].range;
- }
- }
- var serviceDataStr = SaraJSON.stringify(catalogItemData);
- var hash = SaraUtils.md5(serviceDataStr);
- return hash;
- },
- /**
- * Get embedded services from catalogData
- * @param {Object} catalogData
- * @return {Array<Object>|Null}
- */
- getEmbeddedService: function (catalogData, index) {
- if (catalogData['_embedded'] && catalogData['_embedded']['service'] && catalogData['_embedded']['service'][0]) {
- if (index !== undefined) {
- return catalogData['_embedded']['service'][index];
- } else {
- return catalogData['_embedded']['service'];
- }
- } else {
- return null;
- }
- },
- /**
- * Discover services from catalog url of SAPI
- * @param {String} catalogUrl
- * @param {String} catalogTitle
- * @param {Boolean} firstTime
- * @return {Object}
- * - @key {Boolean} error
- * - @key {Object} response
- * - @key {Object} jsonData
- */
- discoverServices: function (catalogUrl, catalogTitle, firstTime) {
- var LOGGER = this.LOGGER;
- var name = catalogUrl.replace(/^.*\/(.*)$/, '$1');
- LOGGER.info('Found catalog "{0}" : {1}', name, catalogUrl);
- LOGGER.info('Starting discoverServices...');
- // Add 'embed=service' flag for getting information of services inside catalog
- catalogUrl += '&embed=service';
- // Make request
- var response = this.makeSAPIRequest(catalogUrl, true);
- if (response.error) {
- LOGGER.error(response.error);
- LOGGER.info('Ended discoverServices!');
- return response;
- }
- // Handle response from SAPI
- var catalogData = response.jsonData;
- var catalogName = catalogData.name;
- // This jsonData will be used for generating hash
- var hashData = response.jsonData2;
- // Do this stuff when first discover
- if (firstTime) {
- // Reference catalog object of SNSC
- var catalogCategory = new SaraModel.CatalogCategory();
- catalogCategory.setTitle(catalogTitle);
- catalogCategory.setName(catalogName);
- catalogCategory.setParent('');
- catalogCategory.setActive(true);
- catalogCategory.setDescription(catalogData.shortDescription);
- // Push catalog object to catalogsData and countData
- LOGGER.info('Push catalog object to catalogsData and countData');
- this.catalogsData[catalogName] = catalogCategory;
- this.servicesData[catalogName] = {};
- this.countData.servicesCount += catalogData.count;
- }
- var servicesData = this.getEmbeddedService(catalogData);
- // Handle services data in '_embedded' resource
- if (servicesData) {
- var servicesLink = catalogData['_links']['service'];
- var SERVICE_ACTIVE = SaraUtils.getSaraProperty(SaraCommon.SYSTEM_PROPERTY_NAME.SERVICE_ACTIVE) === 'true';
- LOGGER.info('Found {0} service(s) of {1} at "{2}"', servicesData.length, catalogName, catalogUrl);
- for (var i = 0, service; service = servicesData[i]; i++) {
- var serviceTitle = servicesLink[i]['title'] || servicesLink[i]['href'].replace(/^.*\/(.*)$/, '$1');
- var isActive = SERVICE_ACTIVE && service['active'];
- // Reference service object of SNSC
- var catalogItem = new SaraModel.CatalogItem();
- catalogItem.setName(serviceTitle || service.name);
- catalogItem.setActive(isActive);
- catalogItem.setWorkflow('Sara Service');
- catalogItem.setShortDesc(service.shortDescription);
- catalogItem.setDescription(SaraUtils.nl2br(service.description));
- catalogItem.setServiceName(service.name);
- catalogItem.setConsumeUrl(service['_links']['consume'][0]['href']);
- catalogItem.setCustomCart(SaraCommon.CUSTOM_CART_NAME);
- // Generate hash of catalogItem without 'range'
- var serviceData = this.getEmbeddedService(hashData, i);
- var hash = this.generateCatalogItemHash(serviceData);
- catalogItem.setHash(hash);
- // Handle variables
- var variables = [];
- for (var index in service.forms) {
- var form = service.forms[index];
- var fields = form.fields;
- for (var index2 in fields) {
- var field = fields[index2];
- var variable = SaraUtils.createCatalogVariable(field);
- variables.push(variable);
- }
- }
- catalogItem.setVariables(variables);
- // Push service object to servicesData
- this.servicesData[catalogName][service.name] = catalogItem;
- }
- } else {
- LOGGER.info('No services found in catalog (name = {0})', catalogName);
- }
- LOGGER.info('Ended discoverServices!');
- // Check the next page
- if (catalogData['_links']['next']) {
- var nextUrl = catalogData['_links']['next'][0]['href'];
- this.discoverServices(nextUrl, catalogTitle);
- }
- },
- /**
- * Discover SAPI consumer URL, create corresponding list of Catalog Category and Catalog Item
- * @return {Object}
- * - @key {Boolean} error
- * - @key {Object} response
- */
- discover: function () {
- var LOGGER = this.LOGGER;
- LOGGER.info('Starting discover...');
- // Check permission before do any discover
- var checkData = this.checkPermission();
- if (checkData.error) {
- this.statusCode = 0;
- this.errorMessage = checkData.error;
- LOGGER.error(checkData.error);
- LOGGER.info('Ended discover!');
- return checkData;
- }
- // Log configuration
- var configData = new SaraConfig().getClientConfig();
- LOGGER.info('OAuth Configuration:\n'
- + ' - Client ID = {0}, \n'
- + ' - Client Secret = ***, \n'
- + ' - Technical User = {1}, \n'
- + ' - SAPI Endpoint = {2}, \n'
- + ' - Token Endpoint = {3}, \n'
- + ' - Authorization Endpoint = {4}, \n'
- + ' - MID Server = {5}',
- configData[SaraCommon.CONFIG_NAME.CLIENT_ID],
- configData[SaraCommon.CONFIG_NAME.TECHNICAL_USER],
- configData[SaraCommon.CONFIG_NAME.SAPI_ENDPOINT],
- configData[SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT],
- configData[SaraCommon.CONFIG_NAME.AUTH_ENDPOINT],
- SaraUtils.getMIDServer()
- );
- /* ================================================================================================
- * Discover root
- * ================================================================================================ */
- this.logMessage('Discovering SAPI root...');
- var rootData = this.discoverRoot();
- // Set percent of progress
- this.incrementPercent(5);
- if (rootData.error) {
- LOGGER.info('Ended discover!');
- return rootData;
- }
- rootData = rootData.jsonData;
- if (!rootData['_links'] || !rootData['_links']['catalogs'][0]) {
- var message = 'No catalog consumer URL found, skip discover!';
- this.errorMessage = message;
- LOGGER.error(message);
- LOGGER.info('Ended discover!');
- return rootData;
- }
- LOGGER.info('Found SAPI Catalogs url: {0}', rootData['_links']['catalogs'][0]['href']);
- /* ================================================================================================
- * Discover catalogs
- * ================================================================================================ */
- this.logMessage('Discovering catalogs...');
- var catalogsData = this.discoverCatalogs(rootData['_links']['catalogs'][0]['href']);
- // Set percent of progress
- this.incrementPercent(5);
- if (catalogsData.error) {
- LOGGER.info('Ended discover!');
- return catalogsData;
- }
- catalogsData = catalogsData.jsonData;
- if (!catalogsData['_links'] || !catalogsData['_links']['catalog'] || !catalogsData['_links']['catalog'][0]) {
- var message = 'No SAPI catalog found, skip discover!';
- this.errorMessage = message;
- LOGGER.error(message);
- LOGGER.info('Ended discover!');
- return catalogsData;
- }
- /* ================================================================================================
- * Discover services
- * ================================================================================================ */
- var totalCatalogs = this.countData.catalogsCount;
- this.percentPerCatalog = 40 / totalCatalogs;
- for (var i in catalogsData['_links']['catalog']) {
- var catalog = catalogsData['_links']['catalog'][i];
- var catalogTitle = catalog.title || catalog.href.replace(/^.*\/(.*)$/, '$1');
- this.logMessage('Discovering services of "{0}" catalog...', catalogTitle);
- // Set limit for catalogUrl
- var catalogUrl = this.getLimitLink(catalog.href, 'services');
- var servicesData = this.discoverServices(catalogUrl, catalogTitle, true);
- // Set percent of progress
- this.incrementPercent(this.percentPerCatalog);
- if (servicesData && servicesData.error) {
- LOGGER.info('Ended discover!');
- return servicesData;
- }
- }
- LOGGER.info('Ended discover!');
- return {
- error: false
- };
- },
- /**
- * Get sys_id of default category named 'Automic Services'
- * @param {String} sys_id
- */
- getDefaultCategoryId: function () {
- var generator = this.generator;
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- var serviceCatalogId = glideHelper.getSysId(SaraCommon.TABLE_NAME.SN_CATALOG, {
- 'title': 'Service Catalog'
- });
- if (!serviceCatalogId) {
- // get the first catalog
- var serviceCatalogId = glideHelper.getSysId(SaraCommon.TABLE_NAME.SN_CATALOG);
- // if there's no catalog, create a new one
- if (!serviceCatalogId) {
- serviceCatalogId = generator.createCatalog('Automic Service Catalog', 'Automic Service Catalog', true);
- LOGGER.info('New catalog \'Automic Service Catalog\' was created');
- }
- }
- var catalogName = glideHelper.getData(SaraCommon.TABLE_NAME.SN_CATALOG, {
- 'sys_id': serviceCatalogId
- }).title;
- LOGGER.info('Using catalog {0}', catalogName);
- // create Automic Service category
- var sysId = glideHelper.getSysId(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'title': this.getDefaultCategory(),
- 'sc_catalog': serviceCatalogId
- });
- if (!sysId) {
- LOGGER.info('Category (name = {0}) doesn\'t exist', this.getDefaultCategory());
- sysId = generator.createDefaultTargetCategory(serviceCatalogId);
- }
- return sysId;
- },
- /**
- * Import catalog category by using 'catalogsData'
- * @param {String} targetCatId Target category id
- */
- importCategory: function (targetCatId) {
- var glideHelper = this.glideHelper;
- var generator = this.generator;
- var LOGGER = this.LOGGER;
- LOGGER.info('Starting importCategory...');
- // If there's no target category specified, all catalogs will be imported as new ones in category named 'Automic Services'
- if (!targetCatId) {
- LOGGER.info('There is no target category, will import catalogs into category (name = "{0}")', this.getDefaultCategory());
- targetCatId = this.getDefaultCategoryId();
- } else {
- LOGGER.info('Target category = "{0}" ...', targetCatId);
- }
- // Save target category id into SaraCommon.TABLE_NAME.SARA_DEFINITION table
- generator.saveTargetCategory(targetCatId);
- // Get name of all catalogs in AE
- var catalogNames = [];
- for (var catalogName in this.catalogsData) {
- catalogNames.push(catalogName);
- }
- LOGGER.info('Catalogs in AE: {0}', catalogNames.join(', '));
- // Get existed catalogs in SNSC
- var existedCatalogs = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_parent': targetCatId,
- 'u_type': 'catalog'
- }, true);
- if (existedCatalogs.length > 0) {
- LOGGER.info('Detecting the existed catalog in SNSC which doesn\'t exist anymore in AE');
- // Remove the existed catalog in SNSC which doesn't exist anymore in AE
- for (var i = 0, saraCatalog; saraCatalog = existedCatalogs[i]; i++) {
- if (!SaraUtils.inArray(catalogNames, saraCatalog.u_name)) {
- LOGGER.info('Catalog with name = {0} doesn\'t exist anymore in AE', saraCatalog.u_name);
- generator.deactivateCategory(saraCatalog);
- }
- }
- }
- // Set percent of progress
- this.incrementPercent(5);
- // Otherwise, check if there's same name category existing under target category
- for (var catalogName in this.catalogsData) {
- var catalog = this.catalogsData[catalogName];
- var catalogId;
- var isNew = true;
- LOGGER.info('Catalog {0}: {1}', catalogName, SaraJSON.stringify(catalog));
- // Check if there's same name category existing under target category
- var targetCategory = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_name': catalog.name,
- 'u_parent': targetCatId,
- 'u_type': 'catalog'
- });
- if (targetCategory) {
- isNew = false;
- catalogId = targetCategory.u_service_catalog_category;
- }
- catalog.setAsNew(isNew);
- catalog.setParent(targetCatId);
- if (isNew) {
- catalogId = generator.saveCategory(catalog);
- catalog.setSysId(catalogId);
- } else {
- // update category with sys_id = catalogId
- catalog.setSysId(catalogId);
- generator.updateCategory(catalog);
- }
- // Set percent of progress
- this.incrementPercent(this.percentPerCatalog);
- }
- LOGGER.info('Refreshing target category (sys_id = {0})', targetCatId);
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': targetCatId
- }, {
- 'active': false
- });
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': targetCatId
- }, {
- 'active': true
- });
- LOGGER.info('Ended importCategory!');
- },
- /**
- * Import catalog item by using 'servicesData' property
- */
- importItem: function () {
- var LOGGER = this.LOGGER;
- LOGGER.info('Starting importItem...');
- var glideHelper = this.glideHelper;
- for (var categoryName in this.servicesData) {
- var isCatalogNew = this.catalogsData[categoryName].isNew();
- var catalogId = this.catalogsData[categoryName].getSysId();
- var items = this.servicesData[categoryName];
- var itemNames = [];
- // Get existed catalog items in AE
- for (var itemName in items) {
- itemNames.push(itemName);
- }
- LOGGER.info('{0} catalog items under category "{1}": {2}', itemNames.length, categoryName, itemNames.join(', '));
- // Get existed catalog items in SNSC
- var existedItems = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_parent': catalogId,
- 'u_type': 'service'
- }, true);
- if (existedItems.length > 0) {
- LOGGER.info('Detecting the existed catalog item in SNSC which doesn\'t exist anymore in AE...');
- // Remove the existed catalog item in SNSC which doesn't exist anymore in AE
- for (var i = 0, saraItem; saraItem = existedItems[i]; i++) {
- if (!SaraUtils.inArray(itemNames, saraItem.u_name)) {
- LOGGER.info('Catalog item (name = {0}, parent sys_id = {1}) doesn\'t exist anymore in AE', saraItem.u_name, saraItem.u_parent);
- this.generator.deleteItem(saraItem);
- }
- }
- }
- for (var itemName in items) {
- var item = items[itemName];
- // Set catalog category sys_id for item
- item.setCategory(catalogId);
- if (isCatalogNew) {
- this.generator.saveItem(item);
- continue;
- }
- // Check existing item with same name and same parent category id = item.category
- var saraItem = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_name': item.getServiceName(),
- 'u_parent': item.getCategory(),
- 'u_type': 'service'
- });
- if (saraItem) {
- this.generator.setItemActive(saraItem, item.isActive());
- // Check hash of saraItem and item
- LOGGER.debug('New and old hash: {0} - {1}', item.getHash(), saraItem.u_hash);
- if (item.getHash() === saraItem.u_hash) {
- LOGGER.info('Item (name = {0}) is not changed', saraItem.u_name);
- new SaraSync().syncLookup(saraItem, item);
- } else {
- LOGGER.info('Item (name = {0}) is changed', saraItem.u_name);
- this.generator.updateItem(saraItem, item);
- }
- } else {
- // Insert new as normal
- this.generator.saveItem(item);
- }
- }
- // Set percent of progress
- this.incrementPercent(this.percentPerCatalog);
- }
- LOGGER.info('Ended importItem!');
- },
- /**
- * Import catalogs and services after discovering by using 'catalogsData' and 'servicesData'
- * @param {String} targetId The id of category which services will be imported in
- */
- doImport: function (targetId) {
- var LOGGER = this.LOGGER;
- LOGGER.info('Starting doImport...');
- if (this.countData.catalogsCount !== 0) {
- this.logMessage('Importing {0} catalog(s)...', this.countData.catalogsCount);
- this.importCategory(targetId);
- if (this.countData.servicesCount !== 0) {
- this.logMessage('Importing {0} service(s)...', this.countData.servicesCount);
- this.importItem();
- } else {
- this.incrementPercent(25);
- LOGGER.info('There are no service be imported!');
- }
- } else {
- this.incrementPercent(50);
- LOGGER.info('There are no catalog be imported!');
- }
- // Make sure that progress always is 100% when completed
- this.incrementPercent(100);
- LOGGER.info('Ended doImport!');
- },
- /**
- * Discover then import the data
- * @param {String} targetId The id of category which services will be imported in
- * @return {String} The log message
- */
- discoverAndImport: function (targetId) {
- var LOGGER = this.LOGGER;
- var response = this.discover();
- var message = '';
- if (response.error) {
- LOGGER.info('Discover data from SAPI not successfully!');
- return null;
- } else {
- message += SaraUtils.formatString('Imported {0} catalog(s) and {1} service(s)!', this.countData.catalogsCount, this.countData.servicesCount);
- this.doImport(targetId);
- return message;
- }
- },
- /**
- * Refresh 'catalogsData' and 'servicesData':
- * - unsetAsNew() for 'catalogsData' item
- * - unsetParent() for 'catalogsData' item
- * - unsetSysId() for 'catalogsData' item
- * - unsetCategory() for 'servicesData' item
- */
- refreshImportedData: function () {
- var LOGGER = this.LOGGER;
- LOGGER.info('Starting refreshImportedData...');
- for (var catalogName in this.catalogsData) {
- var catalogData = this.catalogsData[catalogName];
- catalogData.unsetAsNew();
- catalogData.unsetParent();
- catalogData.unsetSysId();
- }
- for (var catalogName in this.servicesData) {
- var items = this.servicesData[catalogName];
- for (var itemName in items) {
- var item = items[itemName];
- item.unsetCategory();
- }
- }
- LOGGER.info('Ended refreshImportedData!');
- },
- /**
- * Clean up 'catalogsData' and 'servicesData'
- */
- cleanData: function () {
- this.catalogsData = {};
- this.servicesData = {};
- },
- getCatalogsData: function () {
- return this.catalogsData;
- },
- getCatalogData: function (catalogName) {
- return this.catalogsData[catalogName];
- },
- getServicesData: function (catalogName) {
- if (catalogName) {
- return this.servicesData[catalogName];
- } else {
- return this.servicesData;
- }
- },
- getStatusCode: function () {
- return this.statusCode;
- },
- getErrorMessage: function () {
- return this.errorMessage;
- },
- type: 'SaraConsumer'
- };
- ]]></script>
- <description>SaraConsumer class to discover all SAPI catalogs, services and import them into SN as the corresponding catalog categories and items</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraConsumerRunner</name>
- <script><![CDATA[/**
- * Runner for SaraConsumer
- */
- var SaraConsumerRunner = Class.create();
- SaraConsumerRunner.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
- start: function () {
- var LOGGER = new SaraLog(this);
- var targetCatId = this.getParameter('sysparm_catid');
- LOGGER.info('Starting SaraConsumerRunner for importing services into "{0}"...', targetCatId);
- var worker = new GlideScriptedHierarchicalWorker();
- worker.setProgressName('Import Services');
- worker.setBackground(true);
- worker.setScriptIncludeName('x_ausgh_snsc.SaraConsumerWorker');
- worker.setScriptIncludeMethod('run');
- worker.putMethodArg('targetCatId', targetCatId);
- worker.start();
- LOGGER.info('SaraConsumerWorker starts successfully!');
- var progressID = worker.getProgressID();
- LOGGER.info('ID of SaraConsumerWorker is {0}', progressID);
- return progressID;
- },
- type: 'SaraConsumerRunner'
- });
- ]]></script>
- <description>Worker for SaraConsumer</description>
- <active>true</active>
- <client_callable>true</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraConsumerWorker</name>
- <script><![CDATA[/**
- * Worker for SaraConsumer
- */
- var SaraConsumerWorker = Class.create();
- SaraConsumerWorker.prototype = {
- initialize: function () {
- var LOGGER = this.LOGGER = new SaraLog(this);
- var tracker = null;
- try {
- tracker = GlideExecutionTracker.getLastRunning();
- } catch (e) {
- LOGGER.error('Error when getting tracker: {0}', e);
- }
- this.tracker = tracker;
- },
- run: function (targetCatId) {
- if (targetCatId) {
- try {
- var consumer = new SaraConsumer(this.tracker);
- var result = consumer.discoverAndImport(targetCatId);
- if (!result) {
- var statusCode = consumer.getStatusCode();
- var errorMessage = consumer.getErrorMessage();
- if (statusCode != 200) {
- this.updateTrackerResult('Failed to import Automic services', true);
- this.tracker.fail('Got error: ' + statusCode + ' - ' + errorMessage);
- } else {
- this.updateTrackerResult('Got no service or catalog from server.', false);
- this.tracker.success('Got no service or catalog from server.');
- }
- } else {
- this.updateTrackerResult('Imported successfully', false, result);
- this.tracker.success('Imported successfully!');
- }
- } catch (err) {
- this.updateTrackerResult('Failed to import Automic services', true);
- this.tracker.fail(err);
- }
- } else {
- this.updateTrackerResult('Failed to import Automic services', true);
- this.tracker.fail('Target category id is null!');
- }
- },
- /**
- * Update tracker result
- * @param {String} message The message content
- * @param {Boolean} error Error or not
- * @param {String} info The addition information
- */
- updateTrackerResult: function (message, error, info) {
- var LOGGER = this.LOGGER;
- if (error) {
- LOGGER.error(message);
- } else {
- LOGGER.info(message);
- }
- try {
- this.tracker.updateResult({
- msg: message,
- info: info
- });
- } catch (ex) {
- LOGGER.error('Error when updating result for tracker: {0}', ex);
- }
- },
- type: 'SaraConsumerWorker'
- };
- ]]></script>
- <description>Runner for SaraConsumer</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraGlideHelper</name>
- <script><![CDATA[/**
- * Helper class provides convenient methods to work with ServiceNow data tables
- */
- var SaraGlideHelper = Class.create();
- SaraGlideHelper.prototype = {
- initialize: function () {
- },
- /**
- * Common data persistent operation
- * @param {String} table The table name
- * @param {Object} entity Object represents the row to insert
- * @param {Boolean} referencing Insert with references or not
- * @return {String} sys_id of inserted row
- */
- persistData: function (table, entity, referencing) {
- var rec = this._getGlideRecord(table);
- rec.initialize();
- for (key in entity) {
- var value = entity[key];
- if (value === undefined || value === null) {
- value = '';
- }
- // check if key contains 'sys_id'
- var idx = key.indexOf('.sys_id');
- if (idx > 0 && idx == key.length - 7) {
- var propName = key.substring(0, idx);
- rec[propName]['sys_id'] = value;
- } else {
- rec[key] = value;
- }
- }
- if (referencing) {
- return rec.insertWithReferences();
- } else {
- return rec.insert();
- }
- },
- /**
- * Updates record(s) in given table based on the query and entity object holds fields/values to update
- * @param {String} table Target table to update
- * @param {Object} queryObj Query object, property name is the field name to query, value is value to query
- * @param {Object} entity Entity holds fields and values to update
- * @param {Boolean} updateAll Update all matching record(s) or only the first one
- * @param {Boolean} referencing Update with references or not
- */
- updateData: function (table, queryObj, entity, updateAll, referencing) {
- var rec = this._getGlideRecord(table);
- this._buildQuery(rec, queryObj);
- rec.query();
- while (rec.next()) {
- for (key in entity) {
- // check if key contains 'sys_id'
- var idx = key.indexOf('.sys_id');
- if (idx > 0 && idx == key.length - 7) {
- var propName = key.substring(0, idx);
- rec[propName]['sys_id'] = entity[key];
- } else {
- rec[key] = entity[key];
- }
- }
- if (referencing) {
- rec.updateWithReferences();
- } else {
- rec.update();
- }
- if (!updateAll) {
- break;
- }
- }
- },
- /**
- * Retrieve sys_id of a record in given table by key=value query
- * @param {String} table The table name
- * @param {Object} queryObj The object holds the query, property name is the field name to query, value is value to query
- * @param {Boolean} getAll Get sys_id of all matching record(s) or only the first one
- * @return {String|Array<String>} sys_id that found, or null if no record found
- */
- getSysId: function (table, queryObj, getAll) {
- var rec = this._getGlideRecord(table);
- this._buildQuery(rec, queryObj);
- rec.query();
- if (getAll) {
- var results = [];
- while (rec.next()) {
- results.push('' + rec['sys_id']);
- }
- return results;
- } else {
- if (rec.next()) {
- return '' + rec['sys_id'];
- } else {
- return null;
- }
- }
- },
- /**
- * Parse GlideRecordSecure into an object with same properties but value of properties will be converted to String. The
- * original properties will be store in '_origin' property
- * @param {GlideRecordSecure} rec The instance of GlideRecordSecure
- * @return {Object}
- */
- _parseRecord: function (rec) {
- var obj = {
- _origin: rec
- };
- for (var key in rec) {
- try {
- obj[key] = '' + rec[key];
- } catch (e) {
- obj[key] = '' + rec[key].toString();
- }
- }
- return obj;
- },
- /**
- * Query data from given table and query condition, return objects contain information specified in list of key
- * @param {String} table The target table
- * @param {Object} queryObj The object holds the query, property name is the field name to query, value is value to query
- * @param {Boolean} getAll Get all matching record(s) or only the first one
- * @return {Array} Array of object
- */
- getData: function (table, queryObj, getAll) {
- var rec = this._getGlideRecord(table);
- this._buildQuery(rec, queryObj);
- rec.query();
- if (getAll) {
- var result = [];
- while (rec.next()) {
- result.push(this._parseRecord(rec));
- }
- return result;
- } else {
- if (rec.next()) {
- return this._parseRecord(rec);
- } else {
- return null;
- }
- }
- },
- /**
- * Delete record(s) from given table based on a query condition
- * @param {String} table The target table
- * @param {Object} queryObj The object holds the query, property name is the field name to query, value is value to query
- * @param {Boolean} deleteAll Delete all matching record(s) or only the first one
- */
- deleteData: function (table, queryObj, deleteAll) {
- var rec = this._getGlideRecord(table);
- this._buildQuery(rec, queryObj);
- if (deleteAll) {
- rec.deleteMultiple();
- } else {
- rec.query();
- if (rec.next()) {
- rec.deleteRecord();
- }
- }
- },
- /**
- * Build query for GlideRecordSecure and also support Operators
- * @link http://wiki.servicenow.com/index.php?title=Using_GlideRecord_to_Query_Tables
- * @param {GlideRecordSecure} rec
- * @param {Object} queryObj
- * - @key {String} The field name
- * - @value {Array|String|Number} The field value. If array, value will be [Operator, Value]
- */
- _buildQuery: function (rec, queryObj) {
- for (var key in queryObj) {
- var value = queryObj[key];
- if (typeof value === 'object' && value instanceof Array) {
- rec.addQuery(key, value[0], value[1]);
- } else {
- rec.addQuery(key, value);
- }
- }
- },
- /**
- * Get instance of GlideRecordSecure
- * @param {String} table The target table
- * @return {GlideRecordSecure}
- */
- _getGlideRecord: function (table) {
- return new GlideRecordSecure(table);
- },
- _getTableNameByPersistMode: function(table) {
- if(this.persistMode == GlidePersistMode.IMPORT_SET) {
- return table + "_ist";
- }
- },
- type: 'SaraGlideHelper'
- };
- ]]></script>
- <description>Helper class provides convenient methods to work with ServiceNow data tables</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraJSON</name>
- <script><![CDATA[/**
- * Sara JSON Utilities
- */
- var SaraJSON = Class.create();
- SaraJSON.prototype = {
- initialize: function() {},
- type: 'SaraJSON'
- };
- /*
- JSON.js
- 2013-05-26
- Public Domain.
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
- See http://www.JSON.org/js.html
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
- This file creates a global JSON object containing two methods: stringify
- and parse.
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or ' '),
- it contains the characters used to indent at each level.
- This method produces a JSON text from a JavaScript value.
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
- For example, this would serialize Dates as ISO strings.
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
- Example:
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
- Example:
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
- /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
- */
- /*jslint evil: true, regexp: true */
- /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
- */
- (function(JSON) {
- 'use strict';
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
- function toJSON(value) {
- if (value instanceof Date) {
- return isFinite(date.valueOf()) ? date.getUTCFullYear() + '-' +
- f(date.getUTCMonth() + 1) + '-' +
- f(date.getUTCDate()) + 'T' +
- f(date.getUTCHours()) + ':' +
- f(date.getUTCMinutes()) + ':' +
- f(date.getUTCSeconds()) + 'Z' : null;
- } else {
- switch (typeof value) {
- case 'string':
- case 'number':
- case 'boolean':
- return value.valueOf();
- }
- }
- }
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"': '\\"',
- '\\': '\\\\'
- },
- rep;
- function quote(string) {
- // If the string contains no control characters, no quote characters, and no
- // backslash characters, then we can safely slap some quotes around it.
- // Otherwise we must also replace the offending characters with safe escape
- // sequences.
- escapable.lastIndex = 0;
- return escapable.test(string) ? '"' + string.replace(escapable, function(a) {
- var c = meta[a];
- return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' : '"' + string + '"';
- }
- function str(key, holder) {
- // Produce a string from holder[key].
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
- // If the value has a toJSON method, call it to obtain a replacement value.
- if (value && typeof value === 'object' && typeof toJSON(value) === 'function') {
- value = toJSON(value, key);
- }
- // If we were called with a replacer function, then call the replacer to
- // obtain a replacement value.
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
- // What happens next depends on the value's type.
- switch (typeof value) {
- case 'string':
- return quote(value);
- case 'number':
- // JSON numbers must be finite. Encode non-finite numbers as null.
- return isFinite(value) ? String(value) : 'null';
- case 'boolean':
- case 'null':
- // If the value is a boolean or null, convert it to a string. Note:
- // typeof null does not produce 'null'. The case is included here in
- // the remote chance that this gets fixed someday.
- return String(value);
- // If the type is 'object', we might be dealing with an object or an array or
- // null.
- case 'object':
- // Due to a specification blunder in ECMAScript, typeof null is 'object',
- // so watch out for that case.
- /**
- * MUST to check the type of object is Array or not because if value = [''], !value always is true on Rhino
- * @modifiedBy: dhm@automic.com
- */
- if (!value && Object.prototype.toString.apply(value) !== '[object Array]') {
- return 'null';
- }
- // Make an array to hold the partial results of stringifying this object value.
- gap += indent;
- partial = [];
- // Is the value an array?
- if (Object.prototype.toString.apply(value) === '[object Array]') {
- // The value is an array. Stringify every element. Use null as a placeholder
- // for non-JSON values.
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
- // Join all of the elements together, separated with commas, and wrap them in
- // brackets.
- v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
- // If the replacer is an array, use it to select the members to be stringified.
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- if (typeof rep[i] === 'string') {
- k = rep[i];
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
- // Otherwise, iterate through all of the keys in the object.
- for (k in value) {
- if (Object.prototype.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
- // Join all of the member texts together, separated with commas,
- // and wrap them in braces.
- v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
- // If the JSON object does not yet have a stringify method, give it one.
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function(value, replacer, space) {
- // The stringify method takes a value and an optional replacer, and an optional
- // space parameter, and returns a JSON text. The replacer can be a function
- // that can replace values, or an array of strings that will select the keys.
- // A default replacer method can be provided. Use of the space parameter can
- // produce text that is more easily readable.
- var i;
- gap = '';
- indent = '';
- // If the space parameter is a number, make an indent string containing that
- // many spaces.
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
- // If the space parameter is a string, it will be used as the indent string.
- } else if (typeof space === 'string') {
- indent = space;
- }
- // If there is a replacer, it must be a function or an array.
- // Otherwise, throw an error.
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
- // Make a fake root object containing our value under the key of ''.
- // Return the result of stringifying the value.
- return str('', {
- '': value
- });
- };
- }
- // Because with SCOPED_APP, we can't use 'eval' function as the original so we decided to use 'decode' function of
- // ServiceNow's JSON class for our 'SaraJSON.parse'
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function(text, reviver) {
- return new global.JSON().decode(text, reviver);
- };
- }
- })(SaraJSON);
- ]]></script>
- <description>Sara JSON Utilities</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraLog</name>
- <script><![CDATA[/**
- * Log Utilities for Sara
- */
- var SaraLog = Class.create();
- SaraLog.prototype = {
- /**
- * Init logger
- * @param {Object|String} className The class name of object. Will be append after timestamp.
- * If is not String, will get the className from 'type' property of object
- */
- initialize: function (className) {
- this.className = typeof className === 'string' ? className : className.type;
- },
- _log: function (message) {
- return SaraUtils.formatString('[{0}] [{1}] {2}', SaraUtils.getTimeStamp(), this.className, message.toString());
- },
- info: function () {
- var message = SaraUtils.formatString.apply(this, arguments);
- message = this._log(message);
- gs.info(message);
- },
- debug: function () {
- var message = SaraUtils.formatString.apply(this, arguments);
- message = this._log(message);
- gs.debug(message);
- },
- error: function () {
- var message = SaraUtils.formatString.apply(this, arguments);
- message = this._log(message);
- gs.error(message);
- },
- warn: function () {
- var message = SaraUtils.formatString.apply(this, arguments);
- message = this._log(message);
- gs.warn(message);
- },
- type: 'SaraLog'
- };
- ]]></script>
- <description>Log Utilities for Sara</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraModel</name>
- <script><![CDATA[/**
- * SARA concepts modelling in Service Now
- */
- var SaraModel = {}
- /**
- * CatalogItem object represents a SN service catalog item
- * @constructor
- */
- SaraModel.CatalogItem = Class.create();
- SaraModel.CatalogItem.prototype = {
- initialize: function () {},
- setName: function (name) {
- this.name = name;
- },
- getName: function () {
- return this.name;
- },
- setCategory: function (category) {
- this.category = category;
- },
- getCategory: function () {
- return this.category;
- },
- unsetCategory: function () {
- delete this.category;
- },
- setActive: function (active) {
- this.active = active;
- },
- isActive: function () {
- return this.active;
- },
- setWorkflow: function (workflow) {
- this.workflow = workflow;
- },
- getWorkflow: function () {
- return this.workflow;
- },
- setShortDesc: function (shortDesc) {
- this.shortDesc = shortDesc;
- },
- getShortDesc: function (shortDesc) {
- return this.shortDesc;
- },
- setDescription: function (description) {
- this.description = description;
- },
- getDescription: function () {
- return this.description;
- },
- setVariables: function (variables) {
- this.variables = variables;
- },
- getVariables: function (variables) {
- return this.variables;
- },
- setConsumeUrl: function (consumeUrl) {
- this.consumeUrl = consumeUrl;
- },
- getConsumeUrl: function () {
- return this.consumeUrl;
- },
- setServiceName: function (serviceName) {
- this.serviceName = serviceName;
- },
- getServiceName: function () {
- return this.serviceName;
- },
- setCustomCart: function (customCart) {
- this.customCart = customCart;
- },
- getCustomCart: function () {
- return this.customCart;
- },
- setHash: function (hash) {
- this.hash = hash;
- },
- getHash: function () {
- return this.hash;
- },
- type: 'SaraModel.CatalogItem'
- };
- /**
- * CatalogVariable object represents a SN service virable
- * @constructor
- */
- SaraModel.CatalogVariable = Class.create();
- SaraModel.CatalogVariable.prototype = {
- initialize: function () {},
- setName: function (name) {
- this.name = name;
- },
- getName: function () {
- return this.name;
- },
- setType: function (type) {
- this.type = type;
- },
- getType: function () {
- return this.type;
- },
- setLabel: function (label) {
- this.label = label;
- },
- getLabel: function () {
- return this.label;
- },
- setDefaultValue: function (defaultValue) {
- this.defaultValue = defaultValue;
- },
- getDefaultValue: function () {
- return this.defaultValue;
- },
- setDescription: function (description) {
- this.description = description;
- },
- getDescription: function () {
- return this.description;
- },
- setRange: function (range) {
- this.range = range;
- },
- getRange: function () {
- return this.range;
- },
- setActualName: function (actualName) {
- this.actualName = actualName;
- },
- getActualName: function () {
- return this.actualName;
- },
- setAsPassword: function (asPassword) {
- this.asPassword = asPassword;
- },
- isPassword: function (isPassword) {
- return this.asPassword;
- },
- setRequired: function (required) {
- this.required = required;
- },
- isRequired: function (required) {
- return this.required;
- },
- setMultiSelect: function (multiSelect) {
- this.multiSelect = multiSelect;
- },
- isMultiSelect: function (multiSelect) {
- return this.multiSelect;
- },
- setAsLookup: function (asLookup) {
- this.asLookup = asLookup;
- },
- isLookup: function () {
- return this.asLookup;
- },
- setHash: function (hash) {
- this.hash = hash;
- },
- getHash: function () {
- return this.hash;
- },
- type: 'SaraModel.CatalogVariable'
- };
- /**
- * CatalogCategory object represents a SN service catalog category
- * @constructor
- */
- SaraModel.CatalogCategory = Class.create();
- SaraModel.CatalogCategory.prototype = {
- initialize: function () {},
- setTitle: function (title) {
- this.title = title;
- },
- getTitle: function () {
- return this.title;
- },
- setName: function (name) {
- this.name = name;
- },
- getName: function () {
- return this.name;
- },
- setParent: function (parent) {
- this.parent = parent;
- },
- getParent: function () {
- return this.parent;
- },
- unsetParent: function () {
- delete this.parent;
- },
- setActive: function (active) {
- this.active = active;
- },
- isActive: function () {
- return this.active;
- },
- setDescription: function (description) {
- this.description = description;
- },
- getDescription: function () {
- return this.description;
- },
- setConsumeUrl: function (consumeUrl) {
- this.consumeUrl = consumeUrl;
- },
- getConsumeUrl: function () {
- return this.consumeUrl;
- },
- setAsNew: function (asNew) {
- this.asNew = asNew;
- },
- isNew: function () {
- return this.asNew;
- },
- unsetAsNew: function () {
- delete this.asNew;
- },
- setSysId: function (sysId) {
- this.sysId = sysId;
- },
- getSysId: function () {
- return this.sysId;
- },
- unsetSysId: function () {
- delete this.sysId;
- },
- type: 'SaraModel.CatalogCategory'
- };
- ]]></script>
- <description>SARA concepts modelling in Service Now</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>package_private</access>
- </script_include>
- <script_include>
- <name>SaraOAuthAjax</name>
- <script><![CDATA[/**
- * AJAX facade for SaraOAuthClient
- */
- var SaraOAuthAjax = Class.create();
- SaraOAuthAjax.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
- /**
- * Get OAuth URL with redirection endpoint and client id in query string
- * @return {String}
- */
- getOAuthUrl: function () {
- var LOGGER = new SaraLog(this);
- try {
- var clientId = this.getParameter('sysparm_client_id').toString();
- var technicalUser = this.getParameter('sysparm_technical_user').toString();
- var authEndpoint = this.getParameter('sysparm_auth_endpoint').toString();
- var redirectionEndpoint = SaraUtils.getRedirectionUrl();
- LOGGER.info('auth_endpoint={0}; redirect_uri={1}; client_id={2}; technical_user={3}', authEndpoint, redirectionEndpoint, clientId, technicalUser);
- return authEndpoint
- + '?redirect_uri=' + escape(redirectionEndpoint)
- + '&client_id=' + escape(clientId)
- + '&user_info=' + escape(technicalUser)
- + '&user_info_editable=false'
- + '&response_type=code';
- } catch (e) {
- this.logError(e);
- }
- return;
- },
- /**
- * Request token by using Username and password
- * @return {String}
- */
- requestToken: function () {
- var LOGGER = new SaraLog(this);
- try {
- var username = this.getParameter('sysparm_username').toString();
- var password = this.getParameter('sysparm_password').toString();
- var technicalUser = this.getParameter('sysparm_technical_user').toString();
- var oauthClient = new SaraOAuthClient();
- var tokens = oauthClient.requestToken(username, password);
- LOGGER.info('Token: {0}', SaraJSON.stringify(tokens));
- if (tokens && !tokens.error && tokens['access_token']) {
- oauthClient.storeUserTokens(technicalUser, tokens['access_token'], tokens['refresh_token'], tokens['expires_in'], tokens['token_type']);
- return 'ok';
- } else {
- return tokens.error ? tokens.error : (!tokens['access_token'] ? 'Empty result' : '');
- }
- } catch (e) {
- this.logError(e);
- }
- return;
- },
- /**
- * Request token by authorization code
- * @return {String}
- */
- requestTokenByCode: function () {
- var LOGGER = new SaraLog(this);
- try {
- var code = this.getParameter('sysparm_code').toString();
- var technicalUser = this.getParameter('sysparm_technical_user').toString();
- LOGGER.info('Request token for user "{0}" by using code {1}', technicalUser, code);
- var config = {};
- config[SaraCommon.CONFIG_NAME.CLIENT_ID] = this.getParameter('sysparm_client_id').toString();
- config[SaraCommon.CONFIG_NAME.CLIENT_SECERT] = this.getParameter('sysparm_client_secret').toString();
- config[SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT] = this.getParameter('sysparm_token_endpoint').toString();
- var oauthClient = new SaraOAuthClient();
- var tokens = oauthClient.requestTokenByCode(code, config);
- LOGGER.info('Token info: {0}', SaraJSON.stringify(tokens));
- if (tokens && !tokens.error && tokens['access_token']) {
- oauthClient.storeUserTokens(technicalUser, tokens['access_token'], tokens['refresh_token'], tokens['expires_in'], tokens['token_type']);
- return 'ok';
- } else {
- return tokens.error ? tokens.error : (!tokens['access_token'] ? 'Empty result' : '');
- }
- } catch (e) {
- this.logError(e);
- }
- return;
- },
- /**
- * Get client configuration
- */
- getConfig: function () {
- var LOGGER = new SaraLog(this);
- try {
- var configData = new SaraConfig().getClientConfig();
- LOGGER.info('OAuth Configuration: \n'
- + ' - Client ID = {0} \n'
- + ' - Client Secret = *** \n'
- + ' - Technical User = {1} \n'
- + ' - SAPI Endpoint = {2} \n'
- + ' - Token Endpoint = {3} \n'
- + ' - Auth Endpoint = {4} \n',
- configData[SaraCommon.CONFIG_NAME.CLIENT_ID],
- configData[SaraCommon.CONFIG_NAME.TECHNICAL_USER],
- configData[SaraCommon.CONFIG_NAME.SAPI_ENDPOINT],
- configData[SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT],
- configData[SaraCommon.CONFIG_NAME.AUTH_ENDPOINT]
- );
- var config = this.newItem('config');
- for (var key in SaraCommon.CONFIG_NAME) {
- var name = SaraCommon.CONFIG_NAME[key];
- config.setAttribute(name, configData[name]);
- }
- } catch (e) {
- this.logError(e);
- }
- return;
- },
- /**
- * Validate access token key
- */
- validateToken: function () {
- var LOGGER = new SaraLog(this);
- try {
- var technicalUser = this.getParameter('sysparm_technical_user').toString();
- var glideHelper = new SaraGlideHelper();
- var saraOAuth = glideHelper.getData(x_ausgh_snsc.SaraCommon.TABLE_NAME.SARA_OAUTH, {
- 'u_user': technicalUser
- });
- if (saraOAuth) {
- var token = saraOAuth['u_access_token'].toString();
- var sapiEndpoint = this.getParameter('sysparm_sapi_endpoint').toString();
- var oauthClient = new SaraOAuthClient();
- var result = oauthClient.validateToken(token, sapiEndpoint);
- LOGGER.debug('Result of validating token: {0}', result.toString());
- if (typeof result === 'boolean') {
- this.addItem('result', {
- isValid: result
- });
- } else {
- this.addItem('result', {
- message: result
- });
- }
- } else {
- LOGGER.info('Technical User "{1}" does not have tokens', technicalUser);
- this.addItem('result', {
- isValid: false
- });
- }
- } catch (e) {
- this.logError(e);
- }
- return;
- },
- /**
- * Log error
- * @param {Error} error
- * @param {SaraLog} LOGGER
- */
- logError: function (error, LOGGER) {
- LOGGER.error('{0}', error);
- this.addItem('error', {
- message: error
- });
- },
- /**
- * Add item in response
- * @param {String} itemName The name of item
- * @param {Object<String, String>} attributes The object contains item's attributes
- */
- addItem: function (itemName, attributes) {
- var item = this.newItem(itemName);
- for (var name in attributes) {
- var value = attributes[name];
- item.setAttribute(name, value);
- }
- },
- type: 'SaraOAuthAjax'
- });
- ]]></script>
- <description>AJAX facade for SaraOAuthClient</description>
- <active>true</active>
- <client_callable>true</client_callable>
- <access>package_private</access>
- </script_include>
- <script_include>
- <name>SaraOAuthClient</name>
- <script><![CDATA[/**
- * This class contains all OAuth-relaled functions
- */
- var SaraOAuthClient = Class.create();
- SaraOAuthClient.prototype = {
- /**
- * Init new OAuth Client from SaraRESTClient object
- * @param {SaraRestCLient} restClient
- */
- initialize: function (restClient) {
- this.glideHelper = new SaraGlideHelper();
- this.saraConfig = new SaraConfig();
- this.LOGGER = new SaraLog(this);
- if (!restClient) {
- this.restClient = new SaraRESTClient();
- this.restClient.setMIDServer(SaraUtils.getMIDServer());
- } else {
- this.restClient = restClient;
- }
- },
- /**
- * Store user tokens into 'SaraCommon.TABLE_NAME.SARA_OAUTH' table
- * @param {String} username The username which owns tokens
- * @param {String} accessToken The access token of user
- * @param {String} refreshToken The refresh token of user
- * @param {String} tokenExpiry The expiry of token
- * @param {String} tokenType The type of token
- * @return {String} The sys_id of user tokens record
- */
- storeUserTokens: function (username, accessToken, refreshToken, tokenExpiry, tokenType) {
- var LOGGER = this.LOGGER;
- if (!username) {
- LOGGER.info('Store user token: Username must not be empty!');
- return;
- }
- if (!accessToken) {
- LOGGER.info('Error: Access token must be non-empty!');
- return;
- }
- LOGGER.info('Preparing for storing user tokens...');
- // Request tokens of user in 'SaraCommon.TABLE_NAME.SARA_OAUTH' table
- var saraOAuth = this.glideHelper.getData(SaraCommon.TABLE_NAME.SARA_OAUTH, {
- 'u_user': username
- });
- // If user's tokens are existed
- if (saraOAuth) {
- LOGGER.info('User\'s tokens are existed. Updating tokens...');
- this.glideHelper.updateData(SaraCommon.TABLE_NAME.SARA_OAUTH, {
- 'sys_id': saraOAuth['sys_id']
- }, {
- 'u_access_token': accessToken,
- 'u_refresh_token': refreshToken,
- 'u_token_expiry': tokenExpiry,
- 'u_token_type': tokenType
- });
- return saraOAuth['sys_id'];
- } else {
- LOGGER.info('Storing user\'s tokens...');
- return this.glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_OAUTH, {
- 'u_user': username,
- 'u_access_token': accessToken,
- 'u_refresh_token': refreshToken,
- 'u_token_expiry': tokenExpiry,
- 'u_token_type': tokenType
- });
- }
- },
- /**
- * Get user tokens by username. The result will be [accessToken, refreshToken, tokenExpiry, tokenType, { createdAt, createdBy, updateAt, updateBy }]
- * @param {String} username
- * @return {Array<String|Object>}
- */
- getUserTokens: function (username) {
- var LOGGER = this.LOGGER;
- if (!username) {
- return null;
- }
- var saraOAuth = this.glideHelper.getData(SaraCommon.TABLE_NAME.SARA_OAUTH, {
- 'u_user': username
- });
- if (saraOAuth) {
- return [
- saraOAuth['u_access_token'],
- saraOAuth['u_refresh_token'],
- saraOAuth['u_token_expiry'],
- saraOAuth['u_token_type'], {
- 'createdAt': saraOAuth['sys_created_on'],
- 'createdBy': saraOAuth['sys_created_by'],
- 'updatedAt': saraOAuth['sys_updated_on'],
- 'updatedBy': saraOAuth['sys_updated_by']
- }
- ];
- } else {
- LOGGER.info('Tokens of "{0}" do not exist!', username);
- return null;
- }
- },
- /**
- * Remove user tokens by username
- * @param {String} username
- * @return {String} The sys_id of deleted record
- */
- removeUserToken: function (username) {
- var LOGGER = this.LOGGER;
- if (!username) {
- return null;
- }
- var saraOAuth = this.glideHelper.getData(SaraCommon.TABLE_NAME.SARA_OAUTH, {
- 'u_user': username
- });
- if (saraOAuth) {
- saraOAuth = this.glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_OAUTH, {
- 'sys_id': saraOAuth['sys_id']
- });
- return saraOAuth['sys_id'];
- } else {
- LOGGER.info('No token found for user "{0}"', username);
- return null;
- }
- },
- /**
- * Requests user tokens, the request must use client_id/client_secret to authenticate (BASICally) against SARA server,
- * LDAP username/password and grant_type will be embedded in request's body
- * @param {String} username
- * @param {String} password
- * @return {Object} Object contains access token, refresh token, token expiry and token type
- */
- requestToken: function (username, password) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('Preparing for requesting tokens for SARA user {0}...', username);
- var clientInfo = this.saraConfig.getClientConfig();
- var clientId = clientInfo[SaraCommon.CONFIG_NAME.CLIENT_ID];
- var clientSecret = clientInfo[SaraCommon.CONFIG_NAME.CLIENT_SECERT];
- var tokenEndpoint = clientInfo[SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT];
- var request = this.restClient.newOAuthRequest('post', tokenEndpoint);
- request.setBasicAuth(clientId, clientSecret);
- // Add POST body, set Content-Type header
- request.setContentType('application/x-www-form-urlencoded');
- var formEntity = {
- 'grant_type': 'password',
- 'username': username,
- 'password': password
- };
- request.setFormContent(formEntity);
- LOGGER.info('Requesting tokens for SARA user {0}...', username);
- var response = this.restClient.execute(request);
- var responseObject = response.getResponseObject();
- if (response.haveError()) {
- LOGGER.info('Failed to request token for user {0}', username);
- return {
- 'error': responseObject.errorMessage,
- 'error_description': responseObject.errorDescription
- }
- }
- LOGGER.info('Successfully obtain token for user {0}', username);
- return responseObject.bodyObject;
- },
- /**
- * Requests user tokens, the request must use client_id/client_secret to authenticate (BASICally) against SARA server,
- * LDAP redirect_uri/authorization_code and grant_type will be embedded in request's body
- * @param {String} code The authorization code which get from OAuth after logged-in successfully in Auth Endpoint
- * @param {Object} config The config of OAuth Server
- * @return {Object} Object contains access token, refresh token, token expiry and token type
- */
- requestTokenByCode: function (code, config) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('Preparing for requesting tokens by code "{0}"...', code);
- var clientId = config[SaraCommon.CONFIG_NAME.CLIENT_ID];
- var clientSecret = config[SaraCommon.CONFIG_NAME.CLIENT_SECERT];
- var tokenEndpoint = config[SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT];
- var redirectionEndpoint = SaraUtils.getRedirectionUrl();
- var request = this.restClient.newOAuthRequest('post', tokenEndpoint);
- request.setBasicAuth(clientId, clientSecret);
- // Add POST body, set Content-Type header
- request.setContentType('application/x-www-form-urlencoded');
- var formEntity = {
- 'grant_type': 'authorization_code',
- 'redirect_uri': redirectionEndpoint,
- 'code': code
- };
- request.setFormContent(formEntity);
- LOGGER.info('Requesting tokens by code...');
- var response = this.restClient.execute(request);
- var responseObject = response.getResponseObject();
- if (response.haveError()) {
- LOGGER.info('Failed to request token by code');
- return {
- 'error': responseObject.errorMessage,
- 'error_description': responseObject.errorDescription
- }
- }
- LOGGER.info('Successfully obtain token for user by code "{0}"', code);
- return responseObject.bodyObject;
- },
- /**
- * Refresh user tokens
- * @param {String} username
- * @return {Object}
- */
- refreshToken: function (username) {
- var LOGGER = this.LOGGER;
- // Get refresh tokens for this user from 'SaraCommon.TABLE_NAME.SARA_OAUTH' table
- var tokens = this.getUserTokens(username);
- if (!tokens || tokens.length < 1) {
- LOGGER.info('Tokens not found for user {0}', username);
- return null;
- }
- LOGGER.info('Preparing for refreshing tokens for user {0}...', username);
- // Use that refesh token to retrieve new tokens
- var clientInfo = this.saraConfig.getClientConfig();
- var clientId = clientInfo[SaraCommon.CONFIG_NAME.CLIENT_ID];
- var clientSecret = clientInfo[SaraCommon.CONFIG_NAME.CLIENT_SECRET];
- var tokenEndpoint = clientInfo[SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT];
- var request = this.restClient.newOAuthRequest('post', tokenEndpoint);
- request.setBasicAuth(clientId, clientSecret);
- // Add POST body, set Content-Type header
- request.setContentType('application/x-www-form-urlencoded');
- request.setFormContent({
- 'grant_type': 'refresh_token',
- 'refresh_token': tokens[1]
- });
- LOGGER.info('Refreshing tokens for user {0}...', username);
- var response = this.restClient.execute(request);
- var responseObject = response.getResponseObject();
- if (response.haveError()) {
- LOGGER.info('Failed to refresh token for code');
- return {
- 'error': responseObject.errorMessage,
- 'error_description': responseObject.errorDescription
- }
- }
- LOGGER.info('Successfully refresh token for user {0}', username);
- return responseObject.bodyObject;
- },
- /**
- * Validate access token key of user is invalid or expired
- * @param {String} token The access token key of user
- * @param {String} sapiEndpoint The SAPI endpoint
- * @return {Boolean|String}
- */
- validateToken: function (token, sapiEndpoint) {
- var LOGGER = this.LOGGER;
- LOGGER.info('Preparing for validating token "{0}"...', token.toString());
- var configData = this.saraConfig.getClientConfig();
- var request = this.restClient.newSAPIRequest('get', sapiEndpoint);
- request.addHeader('Authorization', 'bearer ' + token);
- var response = this.restClient.executeWithRefreshToken(request);
- var responseObject = response.getResponseObject();
- if (response.haveError()) {
- if (responseObject.statusCode !== 401) {
- var message = SaraUtils.formatString('Error when validating token! Error code: {0} - Error message: {1}', responseObject.statusCode, responseObject.errorMessage);
- LOGGER.error(message);
- return message;
- } else {
- var username = this.saraConfig.getTechnicalUser();
- this.removeUserToken(username);
- return false;
- }
- } else {
- return true;
- }
- },
- type: 'SaraOAuthClient'
- };
- ]]></script>
- <description>This class contains all OAuth-relaled functions</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraRESTClient</name>
- <script><![CDATA[/**
- * Wraps Service Now RESTMessage in a class to provide convenient methods interacting with SARA REST
- */
- var SaraRESTClient = Class.create();
- SaraRESTClient.prototype = {
- initialize: function () {
- this.LOGGER = new SaraLog(this);
- },
- /**
- * Init new service request from SaraRESTMessage class
- * @param {String} name The name of the REST message record
- * @param {String} method The name of the HTTP method to use, such as GET or PUT
- * @param {String} endpoint The endpoint for the REST message
- * @param {Array<String>} basicAuthCreds The basic authentication headers for the REST message
- * @param {Array<Object>} headers The object contains headers for the REST message
- * @param {Array<Object>} stringParameters The object contains string parameters for the REST message
- * @param {Array<Object>} stringParametersNoEscape The object contains string parameters which will be not escaped for the REST message
- * @return {SaraRESTMessage}
- */
- newServiceRequest: function (name, method, endpoint, basicAuthCreds, headers, stringParameters, stringParametersNoEscape) {
- var restMsg = new SaraRESTMessage(name, method);
- if (endpoint) {
- restMsg.setEndpoint(endpoint);
- }
- if (this.midServer) {
- restMsg.setMIDServer(this.midServer);
- }
- if (basicAuthCreds && basicAuthCreds.length > 1) {
- restMsg.setBasicAuth(basicAuthCreds[0], basicAuthCreds[1]);
- }
- if (headers) {
- for (var i = 0, header; header = headers[i]; i++) {
- if (header['name']) {
- restMsg.addHeader(header['name'], header['value']);
- }
- }
- }
- if (stringParameters) {
- for (var i = 0, stringParameter; stringParameter = stringParameters[i]; i++) {
- if (stringParameter['name']) {
- restMsg.setStringParameter(stringParameter['name'], stringParameter['value']);
- }
- }
- }
- if (stringParametersNoEscape) {
- for (var i = 0, stringParameter; stringParameter = stringParametersNoEscape[i]; i++) {
- if (stringParameter['name']) {
- restMsg.setStringParameterNoEscape(stringParameter['name'], stringParameter['value']);
- }
- }
- }
- return restMsg;
- },
- /**
- * Init new SAPI service request from SaraRESTMessage class
- * @param {String} method The name of the HTTP method to use, such as GET or PUT
- * @param {String} endpoint The endpoint for the REST message
- * @param {Array<String>} basicAuthCreds The basic authentication headers for the REST message
- * @param {Array<Object>} headers The object contains headers for the REST message
- * @param {Array<Object>} stringParameters The object contains string parameters for the REST message
- * @param {Array<Object>} stringParametersNoEscape The object contains string parameters which will be not escaped for the REST message
- * @return {SaraRESTMessage}
- */
- newSAPIRequest: function (method, endpoint, basicAuthCreds, headers, stringParameters, stringParametersNoEscape) {
- return this.newServiceRequest(SaraCommon.REST_NAME.SAPI, method, endpoint, basicAuthCreds, headers)
- },
- /**
- * Init new OAuth service request from SaraRESTMessage class
- * @param {String} method The name of the HTTP method to use, such as GET or PUT
- * @param {String} endpoint The endpoint for the REST message
- * @param {Array<String>} basicAuthCreds The basic authentication headers for the REST message
- * @param {Array<Object>} headers The object contains headers for the REST message
- * @param {Array<Object>} stringParameters The object contains string parameters for the REST message
- * @param {Array<Object>} stringParametersNoEscape The object contains string parameters which will be not escaped for the REST message
- * @return {SaraRESTMessage}
- */
- newOAuthRequest: function (method, endpoint, basicAuthCreds, headers, stringParameters, stringParametersNoEscape) {
- return this.newServiceRequest(SaraCommon.REST_NAME.OAUTH, method, endpoint, basicAuthCreds, headers)
- },
- /**
- * Execute REST Message request
- * @param {SaraRESTMessage} saraRest Sara REST Message object
- * @return {SaraRESTResponse}
- */
- execute: function (saraRest) {
- var LOGGER = this.LOGGER;
- LOGGER.info('Making {0} request to {1}...', saraRest.getMethod(), saraRest.getEndpoint());
- LOGGER.debug(saraRest.dump());
- var response;
- if (this.midServer) {
- response = saraRest.executeViaMIDServer(this.midServer);
- } else {
- response = saraRest.execute();
- }
- return response;
- },
- /**
- * Execute REST Message request with automatically get new token if token is expired
- * @param {SaraRESTMessage} saraRest Sara REST Message object
- * @return {SaraRESTResponse}
- */
- executeWithRefreshToken: function (saraRest) {
- var LOGGER = this.LOGGER;
- // First time request
- var response = this.execute(saraRest);
- var responseObject = response.getResponseObject();
- if (response.haveError()) {
- if (responseObject.statusCode === 401) {
- LOGGER.info('Access token of user is invalid or expired');
- var oauthClient = new SaraOAuthClient(this);
- var username = new SaraConfig().getTechnicalUser();
- LOGGER.info('Trying to refresh token for user "{0}"...', username);
- var tokens = oauthClient.refreshToken(username);
- if (tokens && !tokens.error) {
- LOGGER.info('Refresh token finished successfully.');
- oauthClient.storeUserTokens(username, tokens['access_token'], tokens['refresh_token'], tokens['expires_in'], tokens['token_type']);
- // Request again with new token
- saraRest.addHeader('Authorization', 'bearer ' + tokens['access_token']);
- response = this.execute(saraRest);
- } else {
- LOGGER.error('Error when refreshing token');
- if (!tokens) {
- LOGGER.info('Error: {0} - Error description: {1}', tokens.error, tokens.errorDescription);
- oauthClient.removeUserToken(username);
- }
- }
- }
- }
- return response;
- },
- /**
- * Set MID Server
- * @param {String} midServer The MID Server name
- */
- setMIDServer: function (midServer) {
- this.midServer = midServer;
- },
- type: 'SaraRESTClient'
- };
- ]]></script>
- <description>Wraps Service Now RESTMessage in a class to provide convenient methods interacting with SARA REST</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraRESTMessage</name>
- <script><![CDATA[/**
- * Wrap original ServiceNow's RESTMessageV2 class to make HTTP request
- */
- var SaraRESTMessage = Class.create();
- SaraRESTMessage.prototype = {
- /**
- * Init Sara REST Message object
- * @param {String} name Name of REST message record
- * @param {String} method The name of the HTTP method to use, such as GET or PUT
- */
- initialize: function (name, method) {
- method = method.toLowerCase();
- this.restMsg = new sn_ws.RESTMessageV2(name, method);
- this.name = name;
- this.method = method;
- this.LOGGER = new SaraLog(this);
- },
- /**
- * Set the content of the REST message body
- * @param {String} content The content of REST Message
- */
- setContent: function (content) {
- this.restMsg.setRequestBody(content);
- },
- /**
- * Set form content for REST Message
- * @param {Object} formData The object contains form data
- */
- setFormContent: function (formData) {
- if (!formData) {
- return;
- }
- var content = '';
- for (var propName in formData) {
- var value = formData[propName];
- if (value instanceof Array) {
- for (var i = 0; i < value.length; i++) {
- var _value = value[i];
- content += (encodeURIComponent(propName) + '=' + encodeURIComponent(_value) + '&');
- }
- } else {
- content += (encodeURIComponent(propName) + '=' + encodeURIComponent(value) + '&');
- }
- }
- if (content.length > 0) {
- content = content.substring(0, content.length - 1);
- this.setContent(content);
- }
- },
- /**
- * Get the content of the REST message body
- * @return {String}
- */
- getContent: function () {
- return this.restMsg.getRequestBody();
- },
- /**
- * Add headers for REST Message
- * @param {String} key The key of header
- * @param {*} value The value of header
- */
- addHeader: function (key, value) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('addHeader: key = "{0}" and value = "{1}"', key, value);
- this.restMsg.setRequestHeader(key, value);
- },
- /**
- * Add type for header named 'content-type'
- * @param {String} type The content type of REST Message
- */
- setContentType: function (type) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('setContentType: type = "{0}"', type);
- this.addHeader('content-type', type);
- },
- /**
- * Set basic authentication headers for the REST message
- * @param {String} usename
- * @param {String} password
- */
- setBasicAuth: function (username, password) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('setBasicAuth: username = "{0}" and password = "{1}"', username, password);
- this.restMsg.setBasicAuth(username, password);
- },
- /**
- * Set a REST message function variable to the specified value
- * @param {String} name The name of parameter
- * @param {String} value The value of parameter
- */
- setStringParameter: function (name, value) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('setStringParameter: name = "{0}" and value = "{1}"', name, value);
- this.restMsg.setStringParameter(name, value);
- },
- /**
- * Set a REST message function variable to the specified value without escaping XML reserved characters
- * @param {String} name The name of parameter
- * @param {String} value The value of parameter
- */
- setStringParameterNoEscape: function (name, value) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('setStringParameterNoEscape: name = "{0}" and value = "{1}"', name, value);
- this.restMsg.setStringParameterNoEscape(name, value);
- },
- /**
- * Set the endpoint for the REST message
- * @param {String} endpoint
- */
- setEndpoint: function (endpoint) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('setEndpoint: endpoint = "{0}"', endpoint);
- this.restMsg.setEndpoint(endpoint);
- },
- /**
- * Get the URL of the endpoint for the REST message.
- * @return {String}
- */
- getEndpoint: function () {
- return this.restMsg.getEndpoint();
- },
- /**
- * Configure the REST message to communicate through a MID Server.
- * @param {String} midServer The name of MID Server
- */
- setMIDServer: function (midServer) {
- var LOGGER = this.LOGGER;
- LOGGER.debug('setMIDServer: midServer = "{0}"', midServer);
- this.restMsg.setMIDServer(midServer);
- },
- /**
- * Send REST Message to endpoint
- * @return {}
- */
- execute: function () {
- return new SaraRESTResponse(this.restMsg.execute());
- },
- /**
- * Execute REST request via MID Server
- * @param {String} midServer The name of MID Server
- */
- executeViaMIDServer: function (midServer) {
- var LOGGER = this.LOGGER;
- if (midServer) {
- this.restMsg.setMIDServer(midServer);
- this.midServer = midServer;
- LOGGER.info('Using MID Server {0}', this.midServer);
- }
- if (!this.midServer) {
- LOGGER.info('No MID Server defined for the request. Request is aborted!');
- return null;
- }
- return new SaraRESTResponse(this.restMsg.execute(), true);
- },
- /**
- * Get method name of this REST Message
- * @return {String}
- */
- getMethod: function () {
- return this.method.toUpperCase();
- },
- /**
- * Dump information of REST Message
- */
- dump: function () {
- var LOGGER = this.LOGGER;
- try {
- var str = this.getMethod() + ' ' + this.getEndpoint() + ' HTTP/1.1';
- var headers = this.restMsg.getRequestHeaders();
- if (headers) {
- for (key in headers) {
- var value = headers[key];
- if (!gs.nil(value)) {
- if (key === 'Authorization') {
- value = '**********************';
- }
- str += SaraUtils.formatString('\n {0}: {1}', key, value);
- }
- }
- }
- var content = this.getContent();
- if (!gs.nil(content) && content !== 'undefined' && content) {
- str += SaraUtils.formatString('\n\n', content);
- }
- return str;
- } catch (error) {
- LOGGER.info('Error in SaraRESTMessage.dump(): ' + error);
- }
- },
- type: 'SaraRESTMessage'
- };
- ]]></script>
- <description>Class extend from original ServiceNow's RESTMessage class to make HTTP request</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>package_private</access>
- </script_include>
- <script_include>
- <name>SaraRESTResponse</name>
- <script><![CDATA[/**
- * Wrap original ServiceNow's RESTResponseV2 class to handle response of RESTMessageV2
- */
- var SaraRESTResponse = Class.create();
- SaraRESTResponse.prototype = {
- /**
- * Init Sara REST Response object
- * @param {sn_ws.RESTResponseV2} response The response object of RESTResponseV2
- * @param {Boolean} useMIDServer Get response via MID Server or not
- */
- initialize: function (response, useMIDServer) {
- this.response = response;
- var LOGGER = this.LOGGER = new SaraLog(this);
- if (useMIDServer) {
- var timeout = SaraUtils.getSaraProperty(SaraCommon.SYSTEM_PROPERTY_NAME.REST_REQUEST_TIMEOUT);
- LOGGER.debug('Timeout for REST Message: {0}s', timeout);
- response.waitForResponse(timeout);
- }
- if (response.haveError()) {
- LOGGER.info('Error when requesting REST Message: {0} - {1}', response.getErrorCode(), response.getErrorMessage());
- } else {
- LOGGER.info('Status code: {0}', response.getStatusCode());
- }
- LOGGER.debug('Response body: {0}', response.getBody());
- },
- /**
- * Set the amount of time the instance waits for the response
- * @param {Number} timeoutSecs The amount of time, in seconds, to wait for this response.
- */
- waitForResponse: function (timeoutSecs) {
- this.response.waitForResponse(timeoutSecs);
- },
- /**
- * Get the numeric HTTP status code returned by the REST provider
- * @return {Number}
- */
- getStatusCode: function () {
- return this.response.getStatusCode();
- },
- /**
- * Get the value for a specified header
- * @param {Number} timeoutSecs The name of the header that you want the value for, such as Set-Cookie.
- * @return {String}
- */
- getHeader: function (name) {
- return this.response.getHeader(name);
- },
- /**
- * Get all headers returned in the REST response and the associated values
- * @return {Object}
- */
- getHeaders: function () {
- return this.response.getHeaders();
- },
- /**
- * Get the content of the REST response body
- * @return {String}
- */
- getBody: function () {
- return this.response.getBody();
- },
- /**
- * Indicate if there was an error during the REST transaction
- * @return {Boolean}
- */
- haveError: function () {
- return this.response.haveError();
- },
- /**
- * Get the numeric error code if there was an error during the REST transaction. This error code is
- * specific to the ServiceNow platform, it is not an HTTP error code. Provide this error code if you
- * require assistance from ServiceNow Customer Support
- * @return {Number}
- */
- getErrorCode: function () {
- return this.response.getErrorCode();
- },
- /**
- * Get the error message if there was an error during the REST transaction
- * @return {String}
- */
- getErrorMessage: function () {
- return this.response.getErrorMessage();
- },
- /**
- * Get the fully-resolved query sent to the REST endpoint. This query contains the endpoint URL as well
- * as any values assigned to variables in the REST message
- */
- getQueryString: function () {
- return this, response.getQueryString();
- },
- /**
- * Get response body with format is Object
- * @return {Object|Null}
- */
- getBodyObject: function () {
- var LOGGER = this.LOGGER;
- var body = this.getBody();
- if (body) {
- try {
- body = SaraJSON.parse(body);
- } catch (ex) {
- LOGGER.error('Error when parsing response body to Object: {0}', ex);
- }
- }
- return body;
- },
- /**
- * Get response with format is Object. This response contains body object, status code, error message and
- * error description
- * @return {Object}
- */
- getResponseObject: function () {
- var bodyObject = this.getBodyObject();
- var statusCode = this.getStatusCode();
- var errorMessage = this.getErrorMessage();
- var errorDescription = this.getErrorMessage();
- if (bodyObject) {
- if (bodyObject['error']) {
- errorMessage = bodyObject['error'];
- }
- if (bodyObject['error_description']) {
- errorDescription = bodyObject['error_description'];
- }
- }
- return {
- bodyObject: bodyObject,
- statusCode: statusCode,
- errorMessage: errorMessage,
- errorDescription: errorDescription
- }
- },
- type: 'SaraRESTResponse'
- };
- ]]></script>
- <description>Wrap original ServiceNow's RESTResponseV2 class to handle RESTMessageV2 response</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>package_private</access>
- </script_include>
- <script_include>
- <name>SaraSync</name>
- <script><![CDATA[/**
- * Sara Sync Utilities
- */
- var SaraSync = Class.create();
- SaraSync.prototype = {
- initialize: function () {
- this.glideHelper = new SaraGlideHelper();
- this.LOGGER = new SaraLog(this);
- },
- /**
- * Sync services and catalogs of all category which was imported services
- */
- syncServices: function () {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- var importedCategories = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_type': 'category'
- }, true);
- if (importedCategories.length > 0) {
- LOGGER.info('There are {0} target category(s) which were imported services\n', importedCategories.length);
- var consumer = new SaraConsumer();
- var response = consumer.discover();
- if (response.error) {
- LOGGER.error('Discover data from SAPI not successfully. Syncing services is aborted!');
- return;
- } else {
- for (var i = 0, importedCategory; importedCategory = importedCategories[i]; i++) {
- LOGGER.info('Syncing target category (name = {0}, sys_id = {1})', importedCategory.u_name, importedCategory.u_parent);
- consumer.doImport(importedCategory.u_parent);
- consumer.refreshImportedData();
- LOGGER.info('Target category (name = {0}, sys_id = {1}) is synced!', importedCategory.u_name, importedCategory.u_parent);
- }
- }
- } else {
- LOGGER.warn('No target category found. Skip syncServices!');
- }
- },
- /**
- * Update lookup variable
- * @param {Object} saraVariable The variable from SaraCommon.TABLE_NAME.SARA_DEFINITION, has 'sys_id', 'type', 'name', 'u_hash', 'list_table', 'lookup_table' and 'default_value'
- * @param {SaraModel.CatalogVariable} variable
- */
- updateLookupVariable: function (saraVariable, variable) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- LOGGER.info('New and old hash of variable "{0}": {1} - {2}', saraVariable['name'], variable.getHash(), saraVariable['u_hash']);
- if (variable.getHash() === saraVariable['u_hash']) {
- LOGGER.info('Lookup value of variable "{0}" is not changed!', saraVariable['name']);
- } else {
- LOGGER.info('Lookup value of variable "{0}" is changed!', saraVariable['name']);
- // Remove the old data of lookup table
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_LOOKUP, {
- 'u_control_id': saraVariable['sys_id']
- }, true);
- LOGGER.info('Deleted old data of {0} in {1}!', saraVariable['name'], SaraCommon.TABLE_NAME.SARA_LOOKUP);
- var newDefaultValues = [];
- var ranges = variable.getRange();
- // Insert new range values
- for (var i = 0, range; range = ranges[i]; i++) {
- var rangeId = glideHelper.persistData(SaraCommon.TABLE_NAME.SARA_LOOKUP, {
- 'u_key': range.Value,
- 'u_display_name': range.Key,
- 'u_control_id': saraVariable['sys_id']
- });
- if (SaraUtils.inArray(variable.getDefaultValue(), range.Key)) {
- newDefaultValues.push(rangeId);
- }
- }
- LOGGER.info('Inserted new data of {0} in {1}!', saraVariable['name'], SaraCommon.TABLE_NAME.SARA_LOOKUP);
- if (saraVariable['default_value']) {
- newDefaultValues = newDefaultValues.join(',');
- glideHelper.updateData(SaraCommon.TABLE_NAME.SARA_VARIABLE, {
- 'sys_id': saraVariable['sys_id']
- }, {
- 'default_value': newDefaultValues
- });
- LOGGER.info('Updated default value for variable (name = {0}, sys_id = {1}) with new default_value = {2}', saraVariable['name'], saraVariable['sys_id'], newDefaultValues);
- }
- }
- },
- /**
- * Get variable from instance of SaraModel.CatalogItem
- * @param {SaraModel.CatalogItem} catalogItem
- * @param {String} saraVariableName
- * @return {SaraModel.CatalogVariable||Null}
- */
- getVariable: function (catalogItem, saraVariableName) {
- var variables = catalogItem.getVariables();
- for (var i = 0, variable; variable = variables[i]; i++) {
- var variableName = variable.getName();
- if (variableName === saraVariableName) {
- return variable;
- }
- }
- return null;
- },
- /**
- * Sync all lookup values of catalog item
- * @param {String} saraItem The catalog item in SaraCommon.TABLE_NAME.SARA_DEFINITION
- * @param {SaraModel.CatalogItem} catalogItem
- */
- syncLookup: function (saraCatalogItem, catalogItem) {
- var glideHelper = this.glideHelper;
- var LOGGER = this.LOGGER;
- LOGGER.info('Starting syncLookup...');
- if (catalogItem.getVariables()) {
- // Get variable set of catalog item
- var varSetId = saraCatalogItem['u_var_set'];
- LOGGER.info('Found sys_id of variable set of {0} is: {1}', saraCatalogItem['u_name'], varSetId);
- // Get lookup variables of variable set
- var saraLookupVariables = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_VARIABLE, {
- 'variable_set': varSetId,
- 'u_is_lookup': true
- }, true);
- if (saraLookupVariables.length > 0) {
- LOGGER.info('Found {0} lookup variable(s) in variable set (sys_id = {1})', saraLookupVariables.length, varSetId);
- for (var i = 0, saraVariable; saraVariable = saraLookupVariables[i]; i++) {
- var variable = this.getVariable(catalogItem, saraVariable['name']);
- this.updateLookupVariable(saraVariable, variable);
- }
- } else {
- LOGGER.warn('No lookup variable found in variable set (sys_id = {0}). Skip syncLookup!', varSetId);
- }
- } else {
- LOGGER.warn('There\' no variable found in catalog (item name = {0}). Skip syncLookup!', saraCatalogItem['u_name']);
- }
- LOGGER.info('Ended syncLookup!');
- },
- type: 'SaraSync'
- };
- ]]></script>
- <description>Sara Sync Utilities</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraUtils</name>
- <script><![CDATA[/**
- * Sara Utilities
- */
- var SaraUtils = Class.create();
- SaraUtils.prototype = {
- initialize: function () {},
- type: 'SaraUtils'
- };
- /**
- * Format strings
- * @param {String} string The template string
- * @param {String[]} args Zero or more objects to format, supplied either in a comma-delimited list or as an array
- */
- SaraUtils.formatString = function (string) {
- var args = Array.prototype.slice.call(arguments, 1);
- return string.replace(/\{(\d+)\}/g, function (match, number) {
- return typeof args[number] != 'undefined' ? args[number] : match;
- });
- };
- /**
- * Get Sara property
- * @param {String} name Name of sara property
- * @return {String}
- */
- SaraUtils.getSaraProperty = function (name) {
- return gs.getProperty(SaraCommon.PROP_PREFIX + '.' + name);
- };
- /**
- * Get mid servcer
- * @return {String}
- */
- SaraUtils.getMIDServer = function () {
- return SaraUtils.getSaraProperty(SaraCommon.SYSTEM_PROPERTY_NAME.MID_SERVER);
- };
- /**
- * Get timestamp of current
- * @return {String}
- */
- SaraUtils.getTimeStamp = function () {
- return new Date().valueOf();
- };
- /**
- * Get random number
- * @return {String}
- */
- SaraUtils.getRandom = function () {
- return Math.round(Math.random() * 987654321);
- };
- /**
- * Diff time and return 'h, m, s'
- * @param {Number} time1 The first timestamp
- * @param {Number} time2 The second timestamp
- * @return {String}
- */
- SaraUtils.diffTime = function (time1, time2) {
- var difference = time2 - time1;
- var daysDifference = Math.floor(difference / 1000 / 60 / 60 / 24);
- difference -= daysDifference * 1000 * 60 * 60 * 24;
- var hoursDifference = Math.floor(difference / 1000 / 60 / 60);
- difference -= hoursDifference * 1000 * 60 * 60;
- var minutesDifference = Math.floor(difference / 1000 / 60);
- difference -= minutesDifference * 1000 * 60;
- var secondsDifference = Math.floor(difference / 1000);
- difference -= secondsDifference * 1000;
- var result = '';
- if (daysDifference > 0) {
- result += daysDifference + 'd ';
- }
- if (hoursDifference > 0) {
- result += hoursDifference + 'h ';
- }
- if (minutesDifference > 0) {
- result += minutesDifference + 'm ';
- }
- if (secondsDifference > 0) {
- result += secondsDifference + 's ';
- }
- result += difference + 'ms';
- return result;
- };
- /**
- * Convert '\n' to '<br />' in string
- * @param {String} string
- * @return {String}
- */
- SaraUtils.nl2br = function (string) {
- string = string || '';
- return string.replace(/\n/g, '<br />');
- };
- /**
- * Clean all data of SNSC
- */
- SaraUtils.cleanup = function () {
- var glideHelper = new SaraGlideHelper();
- var LOGGER = new SaraLog('SaraUtils');
- var catItemIds = [];
- var varSetIds = [];
- var catCateIds = [];
- var targetCateIds = [];
- // Get list of catalog item from SaraCommon.TABLE_NAME.SARA_DEFINITION table
- var saraItems = glideHelper.getData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {}, true);
- if (saraItems.length > 0) {
- LOGGER.info('Found {0} item(s) in "{1}"', saraItems.length, SaraCommon.TABLE_NAME.SARA_DEFINITION);
- for (var i = 0, saraItem; saraItem = saraItems[i]; i++) {
- if (saraItem['u_sc_item']) {
- catItemIds.push(saraItem['u_sc_item']);
- }
- if (saraItem['u_var_set']) {
- varSetIds.push(saraItem['u_var_set']);
- }
- if (saraItem['u_service_catalog_category']) {
- catCateIds.push(saraItem['u_service_catalog_category']);
- }
- if (saraItem['u_type'] === 'category') {
- targetCateIds.push(saraItem['u_parent']);
- }
- }
- var message = 'There are :';
- message += SaraUtils.formatString('\n - {0} catalog item(s)', catItemIds.length);
- message += SaraUtils.formatString('\n - {0} variable set(s)', varSetIds.length);
- message += SaraUtils.formatString('\n - {0} category(s)', catCateIds.length);
- message += SaraUtils.formatString('\n - {0} target category(s)', targetCateIds.length);
- LOGGER.info(message);
- if (varSetIds.length > 0) {
- LOGGER.info('Removing {0} variable set(s)...', varSetIds.length);
- for (var i = 0, varSetId; varSetId = varSetIds[i]; i++) {
- // Remove all variables belong to above variable sets
- LOGGER.info('Removing variables from variable set {0}...', varSetId);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SN_VARIABLE, {
- 'variable_set': varSetId
- }, true);
- // Remove all variable sets
- LOGGER.info('Removing variable set (sys_id = {0})...', varSetId);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SN_VARIABLE_SET, {
- 'sys_id': varSetId
- }, true);
- }
- }
- // Cleanup service catalog items
- if (catItemIds.length > 0) {
- LOGGER.info('Removing {0} catalog item(s)...', catItemIds.length);
- for (var i = 0, catItemId; catItemId = catItemIds[i]; i++) {
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SN_CATALOG_ITEM, {
- 'sys_id': catItemId
- });
- }
- }
- // Cleanup catalog categories
- if (catCateIds.length > 0) {
- LOGGER.info('Removing {0} catalog category(s)...', catCateIds.length);
- for (var i = 0, catCateId; catCateId = catCateIds[i]; i++) {
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': catCateId
- });
- }
- }
- // Refresh target categories
- if (targetCateIds.length > 0) {
- LOGGER.info('Refreshing {0} target category(s)...', catCateIds.length);
- for (var i = 0, targetCateId; targetCateId = targetCateIds[i]; i++) {
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': targetCateId
- }, {
- 'active': false
- });
- glideHelper.updateData(SaraCommon.TABLE_NAME.SN_CATEGORY, {
- 'sys_id': targetCateId
- }, {
- 'active': true
- });
- LOGGER.info('Target category (sys_id = {0}) is refreshed.', targetCateId);
- }
- }
- LOGGER.info('Cleaning up {0} table ...', SaraCommon.TABLE_NAME.SARA_DEFINITION);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_DEFINITION, {}, true);
- LOGGER.info('Cleaning up {0} table ...', SaraCommon.TABLE_NAME.SARA_VARIABLE);
- glideHelper.deleteData(SaraCommon.TABLE_NAME.SARA_VARIABLE, {}, true);
- } else {
- LOGGER.warn('There is no items in "{0}". Skip cleanup!', SaraCommon.TABLE_NAME.SARA_DEFINITION);
- }
- };
- /**
- * Create catalog variable from field information
- * @param {Object} field
- * @return {SaraModel.CatalogVariable}
- */
- SaraUtils.createCatalogVariable = function (field) {
- var defaultValue = '';
- var varType;
- var isLookupControl = false;
- if (field['default'] && field['default'].length > 0) {
- defaultValue = field['default'];
- }
- switch (field.type) {
- case 'Label':
- varType = SaraCommon.VAR_TYPE.LABEL;
- break;
- case 'Number':
- // SN only have NUM_SCALE variable type but not suitable, just use string
- varType = SaraCommon.VAR_TYPE.SINGLE_LINE_TEXT;
- break;
- case 'String':
- varType = SaraCommon.VAR_TYPE.SINGLE_LINE_TEXT;
- break;
- case 'List':
- varType = field.multiSelect ? SaraCommon.VAR_TYPE.LIST_COLLECTOR : SaraCommon.VAR_TYPE.LOOKUP_SELECT_BOX;
- isLookupControl = true;
- break;
- case 'Time':
- varType = SaraCommon.VAR_TYPE.SINGLE_LINE_TEXT;
- break;
- case 'Date':
- varType = SaraCommon.VAR_TYPE.DATE;
- break;
- case 'Timestamp':
- varType = SaraCommon.VAR_TYPE.DATE_TIME;
- break;
- default:
- break;
- }
- var catalogVariable = new SaraModel.CatalogVariable();
- catalogVariable.setName(this.legitVarName(field.name));
- catalogVariable.setType(varType);
- catalogVariable.setLabel(field.caption);
- catalogVariable.setDefaultValue(defaultValue);
- catalogVariable.setDescription(field.description);
- catalogVariable.setRange([]);
- catalogVariable.setAsLookup(isLookupControl);
- if (field.maskAsPassword) {
- catalogVariable.setAsPassword(field.maskAsPassword);
- }
- if (field.range && field.range[0].values) {
- var rangeValue = field.range[0].values;
- catalogVariable.setRange(rangeValue);
- // Generate range hash for variable
- var hash = SaraUtils.md5(SaraJSON.stringify(rangeValue));
- catalogVariable.setHash(hash);
- }
- if (field.name) {
- catalogVariable.setActualName(field.name);
- }
- if (field.required) {
- catalogVariable.setRequired(field.required);
- }
- if (field.multiSelect) {
- catalogVariable.setMultiSelect(field.multiSelect);
- }
- return catalogVariable;
- };
- /**
- * Legitimates variable name that is not qualified business rule validate_variable_name
- * @param {String} varName
- * @return {String}
- */
- SaraUtils.legitVarName = function (varName) {
- var firstLegal = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
- var firstLetter = varName.charAt(0);
- if (firstLegal.indexOf(firstLetter) == -1) {
- varName = 'v_' + varName;
- }
- var legal = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789';
- for (var i = 0; i < varName.length; i++) {
- var letter = varName.charAt(i);
- if (legal.indexOf(letter) == -1) {
- // replace illegal char with _
- varName = varName.substr(0, i) + '_' + varName.substr(i + 1);
- }
- }
- return varName;
- };
- /**
- * Build url
- * @param {String} url
- * @return {String}
- */
- SaraUtils.buildUrl = function (url) {
- if (!url) {
- url = '';
- }
- var scheme;
- var pattern = /^https?:\/\//i;
- if (pattern.test(url)) {
- scheme = 'absolute';
- } else {
- scheme = 'relative';
- }
- if (scheme === 'relative') {
- var basePath = new SaraConfig().getBasePath();
- if (basePath.charAt(basePath.length - 1) == '/' && url.substring(0, 1) == '/') {
- return basePath + url.substring(1);
- }
- if (basePath.charAt(basePath.length - 1) != '/' && url.substring(0, 1) != '/') {
- return basePath + '/' + url;
- }
- return basePath + url;
- }
- if (url == '/') {
- return new SaraConfig().getBasePath();
- }
- return url;
- };
- /**
- * Gets index of item in array
- * @param {Array} array
- * @param {*} item
- * @return {Number}
- */
- SaraUtils.indexOf = function (array, item) {
- for (var i = 0; i < array.length; ++i) {
- if (array[i] === item) {
- return i;
- }
- }
- return -1;
- };
- /**
- * Detects the array item is in array or not
- * @param {Array} array
- * @param {*} item
- * @return {Boolean}
- */
- SaraUtils.inArray = function (array, item) {
- return SaraUtils.indexOf(array, item) !== -1;
- };
- /**
- * Get redirection endpoint of current instance
- * @return {String} The redirection endpoint
- */
- SaraUtils.getRedirectionUrl = function () {
- return gs.getProperty('glide.servlet.uri') + SaraCommon.SCOPED_APP + '_sara_oauth_callback.do';
- };
- SaraUtils.md5 = function (string, key, raw) {
- /*
- * JavaScript MD5 1.0.1
- * https://github.com/blueimp/JavaScript-MD5
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- *
- * Based on
- * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
- * Digest Algorithm, as defined in RFC 1321.
- * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for more info.
- */
- /*jslint bitwise: true */
- /*global unescape, define */
- 'use strict';
- /*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
- function safe_add(x, y) {
- var lsw = (x & 0xFFFF) + (y & 0xFFFF),
- msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
- }
- /*
- * Bitwise rotate a 32-bit number to the left.
- */
- function bit_rol(num, cnt) {
- return (num << cnt) | (num >>> (32 - cnt));
- }
- /*
- * These functions implement the four basic operations the algorithm uses.
- */
- function md5_cmn(q, a, b, x, s, t) {
- return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
- }
- function md5_ff(a, b, c, d, x, s, t) {
- return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
- }
- function md5_gg(a, b, c, d, x, s, t) {
- return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
- }
- function md5_hh(a, b, c, d, x, s, t) {
- return md5_cmn(b ^ c ^ d, a, b, x, s, t);
- }
- function md5_ii(a, b, c, d, x, s, t) {
- return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
- }
- /*
- * Calculate the MD5 of an array of little-endian words, and a bit length.
- */
- function binl_md5(x, len) {
- /* append padding */
- x[len >> 5] |= 0x80 << (len % 32);
- x[(((len + 64) >>> 9) << 4) + 14] = len;
- var i, olda, oldb, oldc, oldd,
- a = 1732584193,
- b = -271733879,
- c = -1732584194,
- d = 271733878;
- for (i = 0; i < x.length; i += 16) {
- olda = a;
- oldb = b;
- oldc = c;
- oldd = d;
- a = md5_ff(a, b, c, d, x[i], 7, -680876936);
- d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
- c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
- b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
- a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
- d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
- c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
- b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
- a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
- d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
- c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
- b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
- a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
- d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
- c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
- b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
- a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
- d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
- c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
- b = md5_gg(b, c, d, a, x[i], 20, -373897302);
- a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
- d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
- c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
- b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
- a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
- d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
- c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
- b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
- a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
- d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
- c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
- b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
- a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
- d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
- c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
- b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
- a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
- d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
- c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
- b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
- a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
- d = md5_hh(d, a, b, c, x[i], 11, -358537222);
- c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
- b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
- a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
- d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
- c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
- b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
- a = md5_ii(a, b, c, d, x[i], 6, -198630844);
- d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
- c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
- b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
- a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
- d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
- c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
- b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
- a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
- d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
- c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
- b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
- a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
- d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
- c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
- b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
- a = safe_add(a, olda);
- b = safe_add(b, oldb);
- c = safe_add(c, oldc);
- d = safe_add(d, oldd);
- }
- return [a, b, c, d];
- }
- /*
- * Convert an array of little-endian words to a string
- */
- function binl2rstr(input) {
- var i,
- output = '';
- for (i = 0; i < input.length * 32; i += 8) {
- output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
- }
- return output;
- }
- /*
- * Convert a raw string to an array of little-endian words
- * Characters >255 have their high-byte silently ignored.
- */
- function rstr2binl(input) {
- var i,
- output = [];
- output[(input.length >> 2) - 1] = undefined;
- for (i = 0; i < output.length; i += 1) {
- output[i] = 0;
- }
- for (i = 0; i < input.length * 8; i += 8) {
- output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
- }
- return output;
- }
- /*
- * Calculate the MD5 of a raw string
- */
- function rstr_md5(s) {
- return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
- }
- /*
- * Calculate the HMAC-MD5, of a key and some data (raw strings)
- */
- function rstr_hmac_md5(key, data) {
- var i,
- bkey = rstr2binl(key),
- ipad = [],
- opad = [],
- hash;
- ipad[15] = opad[15] = undefined;
- if (bkey.length > 16) {
- bkey = binl_md5(bkey, key.length * 8);
- }
- for (i = 0; i < 16; i += 1) {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
- hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
- return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
- }
- /*
- * Convert a raw string to a hex string
- */
- function rstr2hex(input) {
- var hex_tab = '0123456789abcdef',
- output = '',
- x,
- i;
- for (i = 0; i < input.length; i += 1) {
- x = input.charCodeAt(i);
- output += hex_tab.charAt((x >>> 4) & 0x0F) +
- hex_tab.charAt(x & 0x0F);
- }
- return output;
- }
- /*
- * Encode a string as utf-8
- */
- function str2rstr_utf8(input) {
- return unescape(encodeURIComponent(input));
- }
- /*
- * Take string arguments and return either raw or hex encoded strings
- */
- function raw_md5(s) {
- return rstr_md5(str2rstr_utf8(s));
- }
- function hex_md5(s) {
- return rstr2hex(raw_md5(s));
- }
- function raw_hmac_md5(k, d) {
- return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d));
- }
- function hex_hmac_md5(k, d) {
- return rstr2hex(raw_hmac_md5(k, d));
- }
- if (!key) {
- if (!raw) {
- return hex_md5(string);
- }
- return raw_md5(string);
- }
- if (!raw) {
- return hex_hmac_md5(key, string);
- }
- return raw_hmac_md5(key, string);
- };
- ]]></script>
- <description>Sara Utilities</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- <script_include>
- <name>SaraTestBench</name>
- <script><![CDATA[/*
- Test bench for Sara Scripts
- Create manually in scope of Automic SNSC
- Use background script to execute:
- var test = new SaraTestBench();
- test.execute();
- */
- var SaraTestBench = Class.create();
- SaraTestBench.prototype = {
- initialize: function () {
- },
- execute: function(){
- SaraTest.resetSummary();
- SaraTransformMapTest.testPersistCatalog();
- SaraTransformMapTest.testPersistCategory();
- SaraTransformMapTest.testPersistCatalogItem();
- SaraTransformMapTest.testPersistVariableSet();
- var summary = SaraTest.getSummary();
- gs.info("=======================================================================================");
- gs.info("SUMMARY");
- gs.info("=======================================================================================");
- gs.info("------ TOTAL: " + summary.total);
- gs.info("------ PASS: " + summary.pass);
- gs.info("------ FAIL: " + summary.fail);
- gs.info("------ IGNORE: " + summary.ignore);
- }
- };
- var SaraTransformMapTest = (function(){
- var logger = new SaraLog("SaraGlideHelperTest");
- var glideHelper = new SaraGlideHelper();
- var catalogId = glideHelper.getSysId("sc_catalog", {title: "Service Catalog"});
- gs.info("catelog id: " + catalogId);
- var getCategory = function(title) {
- return glideHelper.getData("sc_category", {title: title });
- };
- var deleteCategory = function(title, deleteAll) {
- glideHelper.deleteData("sc_category", {title: title },deleteAll);
- glideHelper.deleteData("x_ausgh_snsc_sc_category_ist", {title: title },deleteAll);
- }
- var createCategory = function(title, active, description, parent) {
- glideHelper.persistData("x_ausgh_snsc_sc_category_ist", {
- title: title,
- active: active,
- description: description,
- parent: parent,
- sc_catalog: catalogId
- });
- }
- return {
- testPersistCatalog: function() {
- var catalogName = "snsc test catalog";
- glideHelper.deleteData("sc_catalog", {"title": catalogName});
- SaraTest.test("Persist catalog via Importset", function() {
- glideHelper.persistData("x_ausgh_snsc_sc_catalog_ist", {
- title: catalogName,
- description: "test description",
- active: "true"
- });
- var catalog = glideHelper.getData("sc_catalog", {"title": catalogName});
- SaraTest.assert(catalog !== null, "catalog is transformed correctly");
- SaraTest.assert(catalog.title === catalogName, "catalog title is transformed correctly");
- SaraTest.assert(catalog.description === "test description", "catalog description is transformed correctly");
- gs.info("active: " + catalog.active);
- SaraTest.assert(catalog.active, "catalog active is transformed correctly");
- });
- SaraTest.test("Update catalog via Importset", function() {
- glideHelper.persistData("x_ausgh_snsc_sc_catalog_ist", {
- title: catalogName,
- description: "new test description description",
- active: "false"
- });
- var catalog = glideHelper.getData("sc_catalog", {"title": catalogName});
- SaraTest.assert(catalog !== null, "catalog is transformed correctly");
- SaraTest.assert(catalog.description === "new test description description", "catalog description is updated correctly");
- gs.info("active: " + catalog.active);
- SaraTest.assert(catalog.active == "false", "catalog active is updated correctly");
- });
- },
- testPersistCategory: function() {
- var categoryName1 = "snsc test catagory";
- var categoryName2 = "snsc test sub catagory";
- deleteCategory(categoryName1, true);
- deleteCategory(categoryName2, true);
- SaraTest.test("Persist category via Importset", function() {
- var category = getCategory(categoryName1);
- SaraTest.assert(category === null, "category must not exists");
- var category2 = getCategory(categoryName2);
- SaraTest.assert(category2 === null, "sub category must not exists");
- createCategory(categoryName1,true,"test description", null);
- category = getCategory(categoryName1);
- gs.info(SaraJSON.stringify(category));
- SaraTest.assert(category !== null, "Category ImportSet should be transform to category table");
- SaraTest.assert(category.title === categoryName1, "Assert title transform correctly");
- //create via importset table
- createCategory(categoryName2,true,"test sub description", category.sys_id);
- //get real data
- category2 = getCategory(categoryName2);
- SaraTest.assert(category2 !== null, "Sub category ImportSet should be transform to category table");
- SaraTest.assert(category2.title === categoryName2, "Assert title transform correctly");
- var parent = glideHelper.getData("sc_category", {sys_id:category2.parent});
- SaraTest.assert(parent !== null, "Assert parent transform correctly");
- SaraTest.assert(parent.title === categoryName1, "Assert parent transform correctly");
- });
- SaraTest.test("Save category with same name but different parent should create new category", function() {
- //create another category with different parent and assert that new item is
- //inserted to target table
- gs.info("create another record with name " + categoryName2);
- createCategory(categoryName2,true,"test description 2");
- var records = glideHelper.getData("sc_category", {title:categoryName2}, true);
- SaraTest.assert(records.length === 2, "new category is created");
- });
- },
- testPersistCatalogItem: function() {
- var gh = glideHelper;
- var name = "snsc sample catelog item" + SaraUtils.getRandom();
- gs.info("catelog item name: " + name);
- var description = "whatever";
- var short_description = "short descriprion";
- var categoryName = "snsc item category";
- var category = null;
- SaraTest.test("Persist catalog item via Importset", function(){
- //prepare data
- deleteCategory(categoryName, true);
- createCategory(categoryName, true, "");
- category = getCategory(categoryName);
- gs.info("category id: " + category.sys_id);
- SaraTest.assert(category != null, "category is created successfully");
- gh.persistData("x_ausgh_snsc_sc_cat_item_ist", {
- name: name,
- description: description,
- short_description: short_description,
- use_sc_layout: true,
- no_quantity: true,
- category: category.sys_id,
- active: true
- });
- var item = gh.getData("sc_cat_item", {name: name});
- SaraTest.assert(item.name === name, "item is transformed correctly");
- SaraTest.assert(item.description === description, "description is transformed correctly");
- SaraTest.assert(item.short_description === short_description, "short_description is transformed correctly");
- SaraTest.assert(item.use_sc_layout == "true", "use_sc_layout is transformed correctly");
- SaraTest.assert(item.no_quantity == "true", "no_quantity is transformed correctly");
- SaraTest.assert(item.active == "true", "active is transformed correctly");
- SaraTest.assert(item.category === category.sys_id, "category is transformed correctly");
- });
- SaraTest.test("Catalog item same name different category should create new", function() {
- var newCategoryName = categoryName + SaraUtils.getRandom();
- createCategory(newCategoryName, true, "");
- var newCat = getCategory(newCategoryName);
- gs.info("new category id: " + newCat.sys_id);
- gh.persistData("x_ausgh_snsc_sc_cat_item_ist", {
- name: name,
- description: "new description",
- short_description: "new short description",
- use_sc_layout: false,
- no_quantity: false,
- category: newCat.sys_id,
- active: false
- });
- var records = gh.getData("sc_cat_item", {name: name}, true);
- SaraTest.assert(records.length === 2, "new item is created");
- });
- SaraTest.test("Update catalog item via Importset", function(){
- gh.persistData("x_ausgh_snsc_sc_cat_item_ist", {
- name: name,
- description: "new description",
- short_description: "new short description",
- use_sc_layout: false,
- no_quantity: false,
- category: category.sys_id,
- active: false
- });
- var item = gh.getData("sc_cat_item", {name: name, category: category.sys_id});
- SaraTest.assert(item.name === name, "item is transformed correctly");
- SaraTest.assert(item.description === "new description", "description is transformed correctly");
- SaraTest.assert(item.short_description === "new short description", "short_description is transformed correctly");
- SaraTest.assert(item.use_sc_layout == "false", "use_sc_layout is transformed correctly");
- SaraTest.assert(item.no_quantity == "false", "no_quantity is transformed correctly");
- SaraTest.assert(item.active == "false", "active is transformed correctly");
- SaraTest.assert(item.category === category.sys_id, "category is transformed correctly");
- });
- },
- testPersistVariableSet: function() {
- var varSetName = "snsc test variable set " + SaraUtils.getRandom();
- var varSetTitle = "title";
- var varSetDescription = "test description";
- var varSetDisplayName = "display name";
- var varSetTitleNew = "title new";
- var varSetDescriptionNew = "test description new";
- var varSetDisplayNameNew = "display name new";
- glideHelper.deleteData("item_option_new_set", {"name": ["CONTAINS", "snsc test"]}, true);
- SaraTest.test("Persist variable set via Importset", function() {
- glideHelper.persistData("x_ausgh_snsc_item_option_new_set_ist", {
- name: varSetName,
- title: varSetTitle,
- description: varSetDescription,
- display_name: varSetDisplayName
- });
- var varSet = glideHelper.getData("item_option_new_set", {"name": varSetName});
- SaraTest.assert(varSet !== null, "varSet is transformed correctly");
- SaraTest.assert(varSet.name === varSetName, "var set name is transformed correctly");
- SaraTest.assert(varSet.title === varSetTitle, "var set title is transformed correctly");
- SaraTest.assert(varSet.description === varSetDescription, "var set description is transformed correctly");
- SaraTest.assert(varSet.display_name === varSetDisplayName, "var set display name is transformed correctly");
- });
- SaraTest.test("Update var set via Importset", function() {
- glideHelper.persistData("x_ausgh_snsc_item_option_new_set_ist", {
- name: varSetName,
- title: varSetTitleNew,
- description: varSetDescriptionNew,
- display_name: varSetDisplayNameNew
- });
- var varSet = glideHelper.getData("item_option_new_set", {"name": varSetName});
- SaraTest.assert(varSet !== null, "varSet is transformed correctly");
- SaraTest.assert(varSet.name === varSetName, "var set name is transformed correctly");
- SaraTest.assert(varSet.title === varSetTitleNew, "var set title is updated correctly");
- SaraTest.assert(varSet.description === varSetDescriptionNew, "var set description is updated correctly");
- SaraTest.assert(varSet.display_name === varSetDisplayNameNew, "var set display name is updated correctly");
- });
- }
- };
- })();
- var SaraTest = (function() {
- var indent = "";
- var logger = new SaraLog("SaraTest");
- var pass = 0;
- var fail = 0;
- var isIgnore = false;
- var ignored = 0;
- var log = function() {
- logger.info.apply(logger,arguments);
- };
- return {
- resetSummary: function() {
- pass = 0;
- fail = 0;
- ignored = 0;
- },
- getSummary: function() {
- return {
- pass: pass,
- fail: fail,
- ignore: ignored,
- total: pass + fail + ignored
- };
- },
- ignore: function() {
- isIgnore = true;
- },
- assert: function(value, desc) {
- var prefix = ">>>PASS: ";
- if(!value) {
- prefix = "<<<FAIL: ";
- };
- logger.info("{0}{1}{2}", indent, prefix, desc);
- if(!value) {
- var exceptionMsg = prefix + desc;
- throw new Error(exceptionMsg);
- }
- },
- test: function(name, fn) {
- indent = "";
- logger.info("********************************");
- if(isIgnore) {
- logger.info("[IGNORE] {0}", name);
- isIgnore = false;
- ignored++;
- return;
- }
- logger.info("[TEST CASE] {0}", name);
- indent = " ";
- try {
- fn();
- pass++;
- }
- catch(err) {
- gs.error(err);
- fail++;
- }
- indent = "";
- },
- type: "SaraTest"
- };
- })();
- ]]></script>
- <description>Sara Test Bench</description>
- <active>true</active>
- <client_callable>false</client_callable>
- <access>public</access>
- </script_include>
- </script_includes>
- <ui_scripts>
- <ui_script>
- <script_name>SaraVarSet</script_name>
- <script><![CDATA[/**
- * Catalog client script for SaraVariableSet
- */
- var x_ausgh_snsc = x_ausgh_snsc || {};
- x_ausgh_snsc.SaraVarSet = x_ausgh_snsc.SaraVarSet || {};
- (function (SaraVarSet) {
- 'use strict';
- /**
- * OnLoad event handler for Sara variable set
- */
- SaraVarSet.onLoad = function () {
- SaraVarSet.initListCollector();
- SaraVarSet.setSelectBoxWidth();
- };
- /**
- * Init collector filter
- */
- SaraVarSet.initListCollector = function () {
- x_ausgh_snsc.log('Start: SaraVarSet.initListCollector');
- var messageTables = $$('[id$=_select_0_add_remove_message_table]');
- var listWrappers = $$('.list_name');
- for (var i = 0, table; table = messageTables[i]; i++) {
- var name = table.id.replace('_select_0_add_remove_message_table', '');
- var wrapper = listWrappers[i];
- var target;
- var id;
- if (wrapper) {
- target = wrapper;
- } else {
- target = table;
- }
- id = target.nextSibling.id.replace('IO:', '');
- SaraVarSet.getListCollectorData(id, name);
- }
- x_ausgh_snsc.log('End: SaraVarSet.initListCollector');
- };
- /**
- * Get list collector data from lookup table
- * @param {String} id The sys_id of list collector
- * @param {String} name The name of list collector
- */
- SaraVarSet.getListCollectorData = function (id, name) {
- var filterFn = name + 'g_filter';
- var acRequestFn = name + 'acRequest';
- if (window[filterFn] === undefined || window[acRequestFn] === undefined) {
- setTimeout(function () {
- SaraVarSet.getListCollectorData(id, name);
- }, 100);
- return;
- }
- window[filterFn].reset();
- window[filterFn].setQuery('u_control_id=' + id);
- window[acRequestFn](null);
- };
- /**
- * Make all selecbox's width is 250px for preventing the broken of layout when value of option is too long
- */
- SaraVarSet.setSelectBoxWidth = function () {
- x_ausgh_snsc.log('Start: SaraVarSet.setSelectBoxWidth');
- var selectboxes = $$('select.cat_item_option');
- for (var i = 0, selectbox; selectbox = selectboxes[i]; i++) {
- selectbox.style.width = '250px';
- }
- x_ausgh_snsc.log('End: SaraVarSet.setSelectBoxWidth');
- };
- })(x_ausgh_snsc.SaraVarSet);
- ]]></script>
- <description>Catalog client script for SaraVariableSet</description>
- <active>true</active>
- <global>false</global>
- </ui_script>
- <ui_script>
- <script_name>SaraCommon</script_name>
- <script><![CDATA[/**
- * Common client properties for Sara
- */
- var SaraCommon = SaraCommon || {};
- var x_ausgh_snsc = x_ausgh_snsc || {};
- x_ausgh_snsc.SaraCommon = x_ausgh_snsc.SaraCommon || {};
- x_ausgh_snsc.log = function () {
- if (typeof (console) !== 'undefined') {
- if (navigator.appName === 'Microsoft Internet Explorer') {
- if (arguments.length == 1) {
- console.log('[SARA]', arguments[0]);
- } else if (arguments.length === 2) {
- console.log('[SARA]', arguments[0], arguments[1]);
- } else if (arguments.length > 2) {
- console.log('[SARA]', arguments[0], arguments[1], arguments[2]);
- }
- } else {
- console.log('[SARA]', arguments);
- }
- }
- };
- x_ausgh_snsc.config = x_ausgh_snsc.config || {};
- (function (SaraCommon) {
- 'use strict';
- SaraCommon.SCOPED_APP = 'x_ausgh_snsc';
- SaraCommon.CONFIG_NAME = {
- CLIENT_ID: 'client_id',
- CLIENT_SECRET: 'client_secret',
- TECHNICAL_USER: 'technical_user',
- SAPI_ENDPOINT: 'sapi_endpoint',
- TOKEN_ENDPOINT: 'token_endpoint',
- AUTH_ENDPOINT: 'auth_endpoint'
- };
- SaraCommon.CONTROL_NAME = {
- CLIENT_SCRIPTS: 'sara_client_scripts',
- HIDDEN_CONTROL: 'sara_hidden_control'
- };
- })(x_ausgh_snsc.SaraCommon);
- ]]></script>
- <description>Common client properties for Sara</description>
- <active>true</active>
- <global>false</global>
- </ui_script>
- <ui_script>
- <script_name>SaraOAuth</script_name>
- <script><![CDATA[/**
- * Client script for OAuth integration
- */
- var x_ausgh_snsc = x_ausgh_snsc || {};
- x_ausgh_snsc.SaraOAuth = x_ausgh_snsc.SaraOAuth || {};
- (function (SaraOAuth) {
- 'use strict';
- /**
- * Login to OAuth server for authentication
- * @param {String} clientId The client ID of OAuth Server
- * @param {String} technicalUser The tecnical user who owns the tokens
- * @param {String} authEndpoint The authorization endpoint of OAuth Server
- * @param {Object} callback The callback object contains onSuccess and onFail handler
- */
- SaraOAuth.login = function (clientId, technicalUser, authEndpoint, callback) {
- if (confirm('Technical User does not have tokens or Technical User\'s tokens are empty, invalid or expired. Do you want to open OAuth Authorization popup for getting new tokens?')) {
- SaraOAuth.processSuccess = null;
- SaraOAuth.processFail = null;
- if (SaraOAuth.win) {
- SaraOAuth.win.close();
- }
- SaraOAuth.win = null;
- var ga = new x_ausgh_snsc.SaraGlideAjax('SaraOAuthAjax', 'Getting OAuth url...');
- ga.addParam('sysparm_name', 'getOAuthUrl');
- ga.addParam('sysparm_client_id', clientId);
- ga.addParam('sysparm_technical_user', technicalUser);
- ga.addParam('sysparm_auth_endpoint', authEndpoint);
- ga.getXML(function (response) {
- if (callback && callback.onSuccess && typeof (callback.onSuccess) == 'function') {
- SaraOAuth.processSuccess = callback.onSuccess;
- }
- if (callback && callback.onFail && typeof (callback.onFail) == 'function') {
- SaraOAuth.processFail = callback.onFail;
- }
- var w = 500;
- var h = 600;
- var left = (screen.width / 2) - (w / 2);
- var top = (screen.height / 2) - (h / 2);
- var url = response.responseXML.documentElement.getAttribute('answer');
- SaraOAuth.win = window.open(url, 'aelogin', 'width=' + w + ', height=' + h + ', top=' + top + ', left=' + left);
- });
- }
- };
- /**
- * Process response from OAuth server. If is 'ok', will call SaraOAuth.processSuccess callback.
- * If is not 'ok', will log the answer and alert message.
- * @param {*} response The response
- */
- SaraOAuth.processResponse = function (response) {
- if (SaraOAuth.win) {
- SaraOAuth.win.close();
- }
- x_ausgh_snsc.log('Callback response is: ' + response);
- if (response === 'ok') {
- if (SaraOAuth.processSuccess && typeof (SaraOAuth.processSuccess) == 'function') {
- SaraOAuth.processSuccess();
- }
- } else {
- var msg;
- if (typeof (response) == 'string' && response.match('^function') != 'function') {
- msg = x_ausgh_snsc.SaraUtils.formatString('Token request finished unsuccessfully{0}. Please try again later or contact administrators.', response ? (', error: ' + response) : '');
- } else {
- msg = 'Token request finished unsuccessfully! Please try again later or contact administrators.';
- }
- alert(msg);
- if (SaraOAuth.processFail && typeof (SaraOAuth.processFail) == 'function') {
- SaraOAuth.processFail();
- }
- x_ausgh_snsc.log(msg);
- }
- };
- /**
- * Get configuration
- * @param {Function} callback The callback will be called when getting configuration
- * successfully with parametter is object with same keys with x_ausgh_snsc.SaraCommon.CONFIG_NAME
- */
- SaraOAuth.getConfig = function (callback) {
- var configData = {};
- var ga = new x_ausgh_snsc.SaraGlideAjax('SaraOAuthAjax', 'Getting OAuth configuration...');
- ga.addParam('sysparm_name', 'getConfig');
- ga.getXML(function (resp) {
- var config = resp.responseXML.getElementsByTagName('config')[0];
- for (var key in x_ausgh_snsc.SaraCommon.CONFIG_NAME) {
- var name = x_ausgh_snsc.SaraCommon.CONFIG_NAME[key];
- configData[name] = config.getAttribute(name);
- }
- callback.call(this, configData);
- });
- };
- /**
- * Check OAuth Token of current technical user is invalid, expired or empty
- * @param {String} technicalUser The tecnical user who owns the tokens
- * @param {String} sapiEndpoint The SAPI endpoint
- * @param {Boolean} hideWizardSubmit Hide submit button of wizard or not when token is empty, expired
- * or invalid
- * @param {Object<String, Function>} callback The callback object contains callbacks when valid,
- * invalid, error:
- * - onValid(); // Will be called when tokens are existed and valid.
- * - onInvalid(); // Will be called when tokens are existed but invalid.
- * - onError(errorMessage); // Will be called when have any error. 'errorMessage' is error message
- * - onExisted(); // Will be called if current technical user has tokens but not validate the token yet.
- * SaraCommon.TABLE_NAME.SARA_OAUTH table
- */
- SaraOAuth.checkOAuthToken = function (technicalUser, sapiEndpoint, hideWizardSubmit, callback) {
- x_ausgh_snsc.log('checkOAuthToken', technicalUser, sapiEndpoint, hideWizardSubmit, callback);
- var ga = new x_ausgh_snsc.SaraGlideAjax('SaraOAuthAjax', 'Validating token...');
- ga.addParam('sysparm_name', 'validateToken');
- ga.addParam('sysparm_technical_user', technicalUser);
- ga.addParam('sysparm_sapi_endpoint', sapiEndpoint);
- ga.getXML(function (resp) {
- var result = resp.responseXML.getElementsByTagName('result')[0];
- if (result) {
- var isValid = result.getAttribute('isValid');
- // Valid
- if (isValid === 'true') {
- if (hideWizardSubmit) {
- x_ausgh_snsc.SaraUtils.setWizardSubmitVisible(true);
- }
- x_ausgh_snsc.log('Access token is valid');
- if (typeof callback.onValid === 'function') {
- callback.onValid.call(this);
- }
- // Invalid
- } else if (isValid === 'false') {
- if (hideWizardSubmit) {
- x_ausgh_snsc.SaraUtils.setWizardSubmitVisible(false);
- }
- x_ausgh_snsc.log('Access token is invalid');
- if (typeof callback.onInvalid === 'function') {
- callback.onInvalid.call(this);
- }
- // Error
- } else {
- var errorMessage = result.getAttribute('message');
- x_ausgh_snsc.log(errorMessage);
- if (typeof callback.onError === 'function') {
- callback.onError.call(this, errorMessage);
- }
- }
- } else {
- var error = resp.responseXML.getElementsByTagName('error')[0];
- var errorMessage;
- if (error) {
- errorMessage = error.getAttribute('message');
- }
- if (typeof callback.onError === 'function') {
- callback.onError.call(this, errorMessage);
- }
- }
- });
- };
- })(x_ausgh_snsc.SaraOAuth);
- ]]></script>
- <description>Client script for OAuth integration</description>
- <active>true</active>
- <global>false</global>
- </ui_script>
- <ui_script>
- <script_name>SaraUtils</script_name>
- <script><![CDATA[/**
- * Sara Utilities
- */
- var x_ausgh_snsc = x_ausgh_snsc || {};
- x_ausgh_snsc.SaraUtils = x_ausgh_snsc.SaraUtils || {};
- (function (SaraUtils) {
- 'use strict';
- /**
- * Format strings
- * @method format
- * @param {String} string The template string
- * @param {String[]} args Zero or more objects to format, supplied either in a comma-delimited list or as an array
- */
- SaraUtils.formatString = function (string) {
- var args = Array.prototype.slice.call(arguments, 1);
- return string.replace(/{(\d+)}/g, function (match, number) {
- return typeof args[number] != 'undefined' ? args[number] : match;
- });
- };
- /**
- * Get parameter value in current URL
- * @param {String} name The name of parameter
- * @return {String}
- */
- SaraUtils.getParmVal = function (name) {
- name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]');
- var regexS = '[\\?&]' + name + '=([^&#]*)';
- var regex = new RegExp(regexS);
- var results = regex.exec(window.location.href);
- if (results == null) {
- return '';
- } else {
- return unescape(results[1]);
- }
- };
- /**
- * Hide/show submit button of wizard
- * @param {Boolean} isVisible Submit button is visible or not
- */
- SaraUtils.setWizardSubmitVisible = function (isVisible) {
- document.getElementById('expert_next').style.display = isVisible ? '' : 'none';
- };
- /**
- * Set visible of a form control
- * @param {String} name Name of control
- * @param {Boolean} isVisible Control is hidden or visible
- */
- SaraUtils.setFormControlVisible = function (name, isVisible) {
- if (g_form) {
- g_form.setDisplay(name, isVisible);
- }
- }
- })(x_ausgh_snsc.SaraUtils);
- ]]></script>
- <description>Sara Utilities</description>
- <active>true</active>
- <global>false</global>
- </ui_script>
- <ui_script>
- <script_name>SaraGlideAjax</script_name>
- <script><![CDATA[/**
- * Helper class wraps GlideAjax class of ServiceNow and provide Loading Dialog with custom title
- */
- var x_ausgh_snsc = x_ausgh_snsc || {};
- x_ausgh_snsc.SaraGlideAjax = x_ausgh_snsc.SaraGlideAjax || Class.create();
- (function (SaraGlideAjax) {
- 'use strict';
- SaraGlideAjax.prototype = {
- /**
- * Initialize SaraGlideAjax
- * @param {String} className The class name of callable Script Include
- * @param {String} title The title of loading dialog
- */
- initialize: function (className, title) {
- this.title = title;
- this.ga = new GlideAjax(className);
- this.ga.addParam('sysparm_scope', x_ausgh_snsc.SaraCommon.SCOPED_APP);
- this.className = className;
- },
- /**
- * Add parameter for GlideAjax
- * @param {String} key The key of parameter
- * @param {String} value The value of parameter
- */
- addParam: function (key, value) {
- this.ga.addParam(key, value);
- },
- /**
- * Get XML response from server
- * @param {Function} callback The callback will be call after getting response from server
- */
- getXML: function (callback) {
- var loadingDialog = new GlideDialogWindow('hierarchical_progress_viewer');
- loadingDialog.hideCloseButton();
- loadingDialog.setTitle(this.title);
- var className = this.className;
- x_ausgh_snsc.log('Sending request to ' + className + '...');
- this.ga.getXML(function (response) {
- loadingDialog.destroy();
- x_ausgh_snsc.log('Got response from ' + className, response);
- if (typeof callback === 'function') {
- callback.apply(this, arguments);
- }
- });
- },
- type: 'SaraGlideAjax'
- };
- })(x_ausgh_snsc.SaraGlideAjax);
- ]]></script>
- <description>Helper class wraps GlideAjax class of ServiceNow and provide Loading Dialog with custom title</description>
- <active>true</active>
- <global>false</global>
- </ui_script>
- </ui_scripts>
- <ui_pages>
- <ui_page>
- <name>sara_oauth_callback</name>
- <description>OAuth Redirection Endpoint</description>
- <category>general</category>
- <html><![CDATA[<?xml version="1.0" encoding="utf-8" ?>
- <j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
- <g:requires name="x_ausgh_snsc.SaraCommon.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraGlideHelper.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraGlideAjax.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraOAuth.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraUtils.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraVarSet.jsdbx" params="cache=$[jvar_stamp]" />
- <g:ui_form>
- <p>
- <label>Please wait, processing...</label>
- </p>
- </g:ui_form>
- </j:jelly>
- ]]></html>
- <client_script><![CDATA[var parentWin = (window.opener && window.opener.x_ausgh_snsc.SaraOAuth) ? window.opener : window.parent;
- if (!parentWin || !parentWin.x_ausgh_snsc || !parentWin.x_ausgh_snsc.SaraOAuth || !parentWin.x_ausgh_snsc.SaraOAuth.processResponse || typeof(parentWin.x_ausgh_snsc.SaraOAuth.processResponse) !== 'function') {
- window.location.href = '/home.do';
- } else {
- var code = x_ausgh_snsc.SaraUtils.getParmVal('code');
- x_ausgh_snsc.log('Code: ' + code);
- if (code) {
- var clientId = parentWin.x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.CLIENT_ID];
- var clientSecret = parentWin.x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.CLIENT_SECRET];
- var technicalUser = parentWin.x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.TECHNICAL_USER];
- var tokenEndpoint = parentWin.x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT];
- x_ausgh_snsc.log('Client ID: ' + clientId, 'Client Secret: ' + clientSecret, 'Token Endpoint: ' + tokenEndpoint)
- // Invoke x_ausgh_snsc.SaraOAuthAjax to exchange code for tokens
- x_ausgh_snsc.log('Init GlideAjax for requesting token by code...');
- var ga = new x_ausgh_snsc.SaraGlideAjax('SaraOAuthAjax', 'Requesting token by code...');
- ga.addParam('sysparm_name', 'requestTokenByCode');
- ga.addParam('sysparm_code', code);
- ga.addParam('sysparm_client_id', clientId);
- ga.addParam('sysparm_client_secret', clientSecret);
- ga.addParam('sysparm_technical_user', technicalUser);
- ga.addParam('sysparm_token_endpoint', tokenEndpoint);
- ga.getXML(function (response) {
- var answer = response.responseXML.documentElement.getAttribute('answer');
- parentWin.x_ausgh_snsc.SaraOAuth.processResponse(answer);
- });
- } else {
- x_ausgh_snsc.log('Code is empty!');
- parentWin.x_ausgh_snsc.SaraOAuth.processResponse();
- }
- }
- ]]></client_script>
- <processing_script/>
- </ui_page>
- </ui_pages>
- <ui_macros>
- <ui_macro>
- <name>sara_hidden_control</name>
- <description>UI Marco for Sara Hidden Control</description>
- <category>catalog</category>
- <active>true</active>
- <media_type/>
- <xml><![CDATA[<?xml version="1.0" encoding="utf-8" ?>
- <j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
- <script type="text/javascript">
- $j(function () {
- x_ausgh_snsc.SaraUtils.setFormControlVisible(x_ausgh_snsc.SaraCommon.CONTROL_NAME.HIDDEN_CONTROL, false);
- x_ausgh_snsc.SaraVarSet.onLoad();
- });
- </script>
- </j:jelly>
- ]]></xml>
- </ui_macro>
- <ui_macro>
- <name>sara_client_scripts</name>
- <description/>
- <category>catalog</category>
- <active>true</active>
- <media_type/>
- <xml><![CDATA[<?xml version="1.0" encoding="utf-8" ?>
- <j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">
- <g:requires name="x_ausgh_snsc.SaraCommon.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraGlideAjax.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraOAuth.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraUtils.jsdbx" params="cache=$[jvar_stamp]" />
- <g:requires name="x_ausgh_snsc.SaraVarSet.jsdbx" params="cache=$[jvar_stamp]" />
- <script type="text/javascript">
- $j(function () {
- x_ausgh_snsc.SaraUtils.setFormControlVisible(x_ausgh_snsc.SaraCommon.CONTROL_NAME.CLIENT_SCRIPTS, false);
- });
- </script>
- </j:jelly>
- ]]></xml>
- </ui_macro>
- </ui_macros>
- <workflows>
- <workflow>
- <name>Sara Service</name>
- <description>Sara Service workflow</description>
- <start>begin</start>
- <table>sc_req_item</table>
- <active>true</active>
- <published>true</published>
- <stages>
- <stage>
- <name>Initializing</name>
- <order>100</order>
- <value>initializing</value>
- <ola/>
- </stage>
- <stage>
- <name>Transferring</name>
- <order>200</order>
- <value>transferring</value>
- <ola/>
- </stage>
- <stage>
- <name>Transferred</name>
- <order>300</order>
- <value>transferred</value>
- <ola/>
- </stage>
- <stage>
- <name>Transfer Failed</name>
- <order>300</order>
- <value>transfer_failed</value>
- <ola/>
- </stage>
- <stage>
- <name>Consume Failed</name>
- <order>400</order>
- <value>consume_failed</value>
- <ola/>
- </stage>
- <stage>
- <name>Running</name>
- <order>500</order>
- <value>running</value>
- <ola/>
- </stage>
- <stage>
- <name>Ended OK</name>
- <order>900</order>
- <value>ended_ok</value>
- <ola/>
- </stage>
- <stage>
- <name>Ended Failed</name>
- <order>900</order>
- <value>ended_failed</value>
- <ola/>
- </stage>
- <stage>
- <name>Completed</name>
- <order>1000</order>
- <value>completed</value>
- <ola/>
- </stage>
- </stages>
- <activities>
- <activity>
- <name>Begin</name>
- <activity_definition>Begin</activity_definition>
- <stage/>
- <width/>
- <height/>
- <x>1</x>
- <y>1</y>
- <snsc_name>begin</snsc_name>
- </activity>
- <activity>
- <name>Check item's price is 0 or not?</name>
- <activity_definition>If</activity_definition>
- <stage/>
- <width/>
- <height/>
- <x>1</x>
- <y>2</y>
- <snsc_name>check_price</snsc_name>
- <variables>
- <variable>
- <name>script</name>
- <value><![CDATA[function ifScript() {
- var item = (new x_ausgh_snsc.SaraGlideHelper()).getData(x_ausgh_snsc.SaraCommon.TABLE_NAME.SN_CATALOG_ITEM, {
- 'sys_id': current.cat_item.sys_id
- });
- if ((item.price.toString()) === '0') {
- return 'yes';
- }
- return 'no';
- }
- answer = ifScript();
- ]]></value>
- </variable>
- <variable>
- <name>advanced</name>
- <value>1</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Waiting for approval</name>
- <activity_definition>Approval - Group</activity_definition>
- <stage/>
- <width/>
- <height/>
- <x>1</x>
- <y>3</y>
- <snsc_name>waiting_for_approval</snsc_name>
- <variables>
- <variable>
- <name>wait_for</name>
- <value>first_any</value>
- </variable>
- <variable>
- <name>reject_handling</name>
- <value>reject</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Approved</name>
- <activity_definition>Approval Action</activity_definition>
- <stage/>
- <width/>
- <height/>
- <x>2</x>
- <y>3</y>
- <snsc_name>approved</snsc_name>
- <variables>
- <variable>
- <name>action</name>
- <value>approved</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Rejected</name>
- <activity_definition>Approval Action</activity_definition>
- <stage/>
- <width/>
- <height/>
- <x>1</x>
- <y>4</y>
- <snsc_name>rejected</snsc_name>
- <variables>
- <variable>
- <name>action</name>
- <value>rejected</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Initializing</name>
- <activity_definition>Timer</activity_definition>
- <stage>initializing</stage>
- <width/>
- <height/>
- <x>3</x>
- <y>3</y>
- <snsc_name>initializing</snsc_name>
- <variables>
- <variable>
- <name>timer_type</name>
- <value>script</value>
- </variable>
- <variable>
- <name>script</name>
- <value><![CDATA[workflow.info('Initializing ...');
- var currentUser = current.opened_by.user_name.toString();
- workflow.info('Workflow started by {0}', currentUser);
- workflow.scratchpad.openedBy = currentUser;
- var technicalUser = new x_ausgh_snsc.SaraConfig().getTechnicalUser();
- workflow.info('Technical user: {0}', technicalUser);
- workflow.scratchpad.technicalUser = technicalUser;
- // Set 'answer' to the number of seconds this timer should wait
- answer = 2;
- ]]></value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Invoke Consume URL</name>
- <activity_definition>Run Script</activity_definition>
- <stage>transferring</stage>
- <width/>
- <height/>
- <x>4</x>
- <y>3</y>
- <snsc_name>invoke_consume</snsc_name>
- <variables>
- <variable>
- <name>script</name>
- <value><![CDATA[var restClient = new x_ausgh_snsc.SaraRESTClient();
- restClient.setMIDServer(x_ausgh_snsc.SaraUtils.getMIDServer());
- var oauthClient = new x_ausgh_snsc.SaraOAuthClient(restClient);
- var glideHelper = new x_ausgh_snsc.SaraGlideHelper();
- // Get tokens, store tokens in workflow scratchpad
- var tokens = oauthClient.getUserTokens(workflow.scratchpad.technicalUser);
- if (!tokens) {
- workflow.info('Cannot find access tokens for this user "{0}". Order will be skipped', workflow.scratchpad.technicalUser);
- } else {
- workflow.scratchpad.executionHref = null;
- workflow.scratchpad.isTransfered = false;
- // get service name & consume URL
- var serviceName, consumeUrl, varSetId;
- var catId = current.cat_item.sys_id;
- var saraItem = glideHelper.getData(x_ausgh_snsc.SaraCommon.TABLE_NAME.SARA_DEFINITION, {
- 'u_sc_item': catId
- });
- if (saraItem) {
- serviceName = saraItem['u_name'];
- consumeUrl = saraItem['u_consume_url'];
- varSetId = saraItem['u_var_set'];
- consumeUrl = x_ausgh_snsc.SaraUtils.buildUrl(consumeUrl);
- workflow.info('Service name = {0}', serviceName);
- workflow.info('Consume URL = {0}', consumeUrl);
- workflow.info('Cat item = {0}', current.cat_item.name);
- var payload = {};
- var payloadFields = {};
- payload.fieldvalues = payloadFields;
- if (varSetId) {
- var saraVariables = glideHelper.getData(x_ausgh_snsc.SaraCommon.TABLE_NAME.SARA_VARIABLE, {
- 'variable_set': varSetId
- }, true);
- for (var i = 0, variable; variable = saraVariables[i]; i++) {
- var variableName = variable['name'];
- if (variableName !== x_ausgh_snsc.SaraCommon.CONTROL_NAME.CLIENT_SCRIPTS
- && variableName !== x_ausgh_snsc.SaraCommon.CONTROL_NAME.HIDDEN_CONTROL
- && variable['u_name']) {
- var currentVariable = current.variables[variableName];
- var currentValue;
- if (variable['type'] === x_ausgh_snsc.SaraCommon.VAR_TYPE.LIST_COLLECTOR.toString()) {
- var values = currentVariable.toString().split(',');
- currentValue = [];
- for (var j = 0, value; value = values[j]; j++) {
- var realValue = glideHelper.getData(x_ausgh_snsc.SaraCommon.TABLE_NAME.SARA_LOOKUP, {
- 'sys_id': value
- });
- currentValue.push(realValue['u_display_name']);
- }
- } else {
- currentValue = [currentVariable.getDisplayValue()];
- }
- payloadFields[variable['u_name']] = currentValue;
- }
- }
- } else {
- workflow.info('There is no variables in catalog item (sys_id = {0})', catId);
- }
- //---------------- audit information ---------------
- workflow.info('Add audit information');
- var payloadParams = {};
- payloadParams[x_ausgh_snsc.SaraCommon.AUDIT.ORDER_ID] = current.request.number.toString();
- payloadParams[x_ausgh_snsc.SaraCommon.AUDIT.ORDER_TIMESTAMP] = current.sys_created_on.toString();
- payloadParams[x_ausgh_snsc.SaraCommon.AUDIT.ORDER_NAME] = current.sys_created_by.toString();
- var approvalHistory = '<<Auto Approval>>';
- if(current.approval_history != null) {
- var journal = glideHelper.getData(x_ausgh_snsc.SaraCommon.TABLE_NAME.SN_JOURNAL_FIELD, {
- 'element_id' : current.sys_id
- });
- if(journal != null) {
- approvalHistory = journal.value.toString();
- }
- }
- payloadParams[x_ausgh_snsc.SaraCommon.AUDIT.APPROVAL_HISTORY] = approvalHistory;
- payloadParams[x_ausgh_snsc.SaraCommon.AUDIT.APPROVAL_TIMESTAMP] = current.approval_set.toString();
- payload.parametervalues = payloadParams;
- //--------------- /audit information ---------------
- var payloadStr = x_ausgh_snsc.SaraJSON.stringify(payload);
- workflow.info(payloadStr);
- // Make request
- if (serviceName) {
- workflow.info('Invoking consume URL...');
- var request = restClient.newSAPIRequest('post', consumeUrl);
- request.setContent('${payload}');
- request.addHeader('content-type', 'application/json;charset=UTF-8');
- request.setStringParameterNoEscape('payload', payloadStr);
- // Add Authorization header
- request.addHeader('Authorization', tokens[3] + ' ' + tokens[0]);
- var response = restClient.executeWithRefreshToken(request);
- var responseObject = response.getResponseObject();
- if (response.haveError()) {
- workflow.info('Order process FAILED.');
- } else {
- workflow.info('Successfully transfered.');
- workflow.info('Response: {0}', response.getBody());
- var resObj = x_ausgh_snsc.SaraJSON.parse(response.getBody());
- var runId = resObj['runID'];
- workflow.scratchpad.isTransfered = true;
- if (runId !== undefined) {
- var executionHref = resObj['_links']['self']['href'];
- workflow.info('Got runId: {0}', runId.toString());
- workflow.info('Got execution href: {0}', executionHref);
- workflow.scratchpad.runId = runId;
- workflow.scratchpad.executionHref = executionHref;
- // save runId to the 'correlation_id' column of current record in 'sc_req_item' table
- current['correlation_id'] = '' + runId;
- current.update();
- } else {
- workflow.info(resObj.message);
- }
- }
- } else {
- workflow.info('Failed to make consume request as no service definition was defined.');
- }
- } else {
- workflow.info('Catalog item (sys_id = {0}) doesn\'t existed any more in {1}!', [catId, x_ausgh_snsc.SaraCommon.TABLE_NAME.SARA_DEFINITION]);
- }
- }
- ]]></value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Check transfer result</name>
- <activity_definition>If</activity_definition>
- <stage>transferred</stage>
- <width/>
- <height/>
- <x>5</x>
- <y>3</y>
- <snsc_name>check_transfer</snsc_name>
- <variables>
- <variable>
- <name>script</name>
- <value><![CDATA[// This script needs to set answer to 'yes' or 'no' to indicate the state of the activity.
- //
- // For example,
- //
- answer = ifScript();
- function ifScript() {
- return (workflow.scratchpad.isTransfered == true ? 'yes' : 'no');
- }
- ]]></value>
- </variable>
- <variable>
- <name>advanced</name>
- <value>1</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Transfer Request Failed</name>
- <activity_definition>Log Message</activity_definition>
- <stage>transfer_failed</stage>
- <width/>
- <height/>
- <x>5</x>
- <y>4</y>
- <snsc_name>transfer_failed</snsc_name>
- <variables>
- <variable>
- <name>message</name>
- <value>Transfer request failed, order skipped.</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Check consume result</name>
- <activity_definition>If</activity_definition>
- <stage>transferred</stage>
- <width/>
- <height/>
- <x>6</x>
- <y>4</y>
- <snsc_name>check_consume</snsc_name>
- <variables>
- <variable>
- <name>script</name>
- <value><![CDATA[// This script needs to set answer to 'yes' or 'no' to indicate the state of the activity.
- //
- // For example,
- //
- answer = ifScript();
- function ifScript() {
- return (workflow.scratchpad.executionHref != null ? 'yes' : 'no');
- }
- ]]></value>
- </variable>
- <variable>
- <name>advanced</name>
- <value>1</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Consume Request Failed</name>
- <activity_definition>Log Message</activity_definition>
- <stage>consume_failed</stage>
- <width/>
- <height/>
- <x>6</x>
- <y>5</y>
- <snsc_name>consume_failed</snsc_name>
- <variables>
- <variable>
- <name>message</name>
- <value>Consume request failed, order skipped.</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Workflow Timer</name>
- <activity_definition>Timer</activity_definition>
- <stage>running</stage>
- <width/>
- <height/>
- <x>7</x>
- <y>5</y>
- <snsc_name>workflow_timer</snsc_name>
- <variables>
- <variable>
- <name>timer_type</name>
- <value>script</value>
- </variable>
- <variable>
- <name>script</name>
- <value><![CDATA[if (workflow.scratchpad.delay === undefined) {
- var delay = +x_ausgh_snsc.SaraUtils.getSaraProperty(SaraCommon.SYSTEM_PROPERTY_NAME.WORKFLOW_DELAY);
- var timeout = +x_ausgh_snsc.SaraUtils.getSaraProperty(SaraCommon.SYSTEM_PROPERTY_NAME.WORKFLOW_TIMEOUT);
- // If delay time in config is equal or lesser than 0, let make it '60'
- if (delay <= 0) {
- delay = 60;
- }
- // Make sure that timeout minimum always be '0'
- if (timeout < 0) {
- timeout = 0;
- }
- workflow.scratchpad.counter = 1;
- workflow.scratchpad.maxCount = (timeout / delay) + 1;
- workflow.scratchpad.delay = delay;
- workflow.scratchpad.timeout = timeout;
- }
- answer = workflow.scratchpad.delay;
- ]]></value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Retrieve Execution Status</name>
- <activity_definition>Run Script</activity_definition>
- <stage>running</stage>
- <width/>
- <height/>
- <x>8</x>
- <y>5</y>
- <snsc_name>retrieve_status</snsc_name>
- <variables>
- <variable>
- <name>script</name>
- <value><![CDATA[var restClient = new x_ausgh_snsc.SaraRESTClient();
- restClient.setMIDServer(x_ausgh_snsc.SaraUtils.getMIDServer());
- var oauthClient = new x_ausgh_snsc.SaraOAuthClient(restClient);
- var executionHref = x_ausgh_snsc.SaraUtils.buildUrl(workflow.scratchpad.executionHref);
- workflow.scratchpad.ended = 'unknown';
- // Get tokens, store tokens in workflow scratchpad
- var tokens = oauthClient.getUserTokens(workflow.scratchpad.technicalUser);
- var request = restClient.newSAPIRequest('get', executionHref);
- request.addHeader('Authorization', tokens[3] + ' ' + tokens[0]);
- workflow.info('[{0}] Waiting for execution checking response ...', workflow.scratchpad.counter);
- var response = restClient.executeWithRefreshToken(request);
- var responseObject = response.getResponseObject();
- if (response.haveError()) {
- workflow.warn('Status code: {0}, error message: {1}', [responseObject.statusCode, responseObject.errorMessage]);
- workflow.info('Stop retrieving execution status now.');
- } else {
- workflow.info('Response received: {0}', response.getBody());
- var resObj = responseObject.bodyObject;
- var statusCode = resObj.statusCode;
- workflow.info('Status code: {0}, statusText: {1}', [statusCode.toString(), resObj.statusText]);
- if (statusCode >= 1800) {
- if (statusCode === x_ausgh_snsc.SaraCommon.WORKFLOW_STATUS_CODE.ENDED_OK) {
- workflow.info('Execution finished successfully!');
- workflow.scratchpad.ended = 'ENDED_OK';
- } else {
- workflow.scratchpad.ended = statusCode + ' - ' + resObj.statusText;
- }
- }
- }
- workflow.scratchpad.counter++;
- ]]></value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Check Timeout</name>
- <activity_definition>If</activity_definition>
- <stage>running</stage>
- <width/>
- <height/>
- <x>9</x>
- <y>5</y>
- <snsc_name>check_timeout</snsc_name>
- <variables>
- <variable>
- <name>script</name>
- <value><![CDATA[function ifScript() {
- var counter = workflow.scratchpad.counter;
- var maxCount = workflow.scratchpad.maxCount;
- var timeout = workflow.scratchpad.timeout;
- if (timeout === 0) {
- if (workflow.scratchpad.ended !== 'unknown') {
- return 'yes';
- }
- } else {
- if (counter <= maxCount) {
- if (workflow.scratchpad.ended !== 'unknown') {
- return 'yes';
- }
- } else {
- return 'yes';
- }
- }
- return 'no';
- }
- answer = ifScript();
- ]]></value>
- </variable>
- <variable>
- <name>advanced</name>
- <value>1</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Check Execution Result</name>
- <activity_definition>If</activity_definition>
- <stage>running</stage>
- <width/>
- <height/>
- <x>10</x>
- <y>6</y>
- <snsc_name>check_result</snsc_name>
- <variables>
- <variable>
- <name>script</name>
- <value><![CDATA[// This script needs to set answer to 'yes' or 'no' to indicate the state of the activity.
- answer = ifScript();
- function ifScript() {
- return (workflow.scratchpad.ended == 'ENDED_OK' ? 'yes' : 'no');
- }
- ]]></value>
- </variable>
- <variable>
- <name>advanced</name>
- <value>1</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Ended Failed</name>
- <activity_definition>Log Message</activity_definition>
- <stage>ended_failed</stage>
- <width/>
- <height/>
- <x>10</x>
- <y>7</y>
- <snsc_name>ended_failed</snsc_name>
- <variables>
- <variable>
- <name>message</name>
- <value>Workflow finished NOT OK.</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>Ended OK</name>
- <activity_definition>Log Message</activity_definition>
- <stage>ended_ok</stage>
- <width/>
- <height/>
- <x>11</x>
- <y>7</y>
- <snsc_name>ended_ok</snsc_name>
- <variables>
- <variable>
- <name>message</name>
- <value>Workflow finished successfully.</value>
- </variable>
- </variables>
- </activity>
- <activity>
- <name>End</name>
- <activity_definition>End</activity_definition>
- <stage>completed</stage>
- <width/>
- <height/>
- <x>2</x>
- <y>8</y>
- <snsc_name>end</snsc_name>
- </activity>
- </activities>
- <transitions>
- <transition>
- <from>begin</from>
- <to>check_price</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_price</from>
- <to>waiting_for_approval</to>
- <condition>
- <name>No</name>
- <condition>activity.result == 'no'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_price</from>
- <to>approved</to>
- <condition>
- <name>Yes</name>
- <condition>activity.result == 'yes'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>waiting_for_approval</from>
- <to>rejected</to>
- <condition>
- <name>Rejected</name>
- <condition>activity.result == 'rejected'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>rejected</from>
- <to>end</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>waiting_for_approval</from>
- <to>approved</to>
- <condition>
- <name>Approved</name>
- <condition>activity.result == 'approved' || activity.result == 'skipped'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>approved</from>
- <to>initializing</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>initializing</from>
- <to>invoke_consume</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>invoke_consume</from>
- <to>check_transfer</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_transfer</from>
- <to>transfer_failed</to>
- <condition>
- <name>No</name>
- <condition>activity.result == 'no'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>transfer_failed</from>
- <to>end</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_transfer</from>
- <to>check_consume</to>
- <condition>
- <name>Yes</name>
- <condition>activity.result == 'yes'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_consume</from>
- <to>consume_failed</to>
- <condition>
- <name>No</name>
- <condition>activity.result == 'no'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>consume_failed</from>
- <to>end</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_consume</from>
- <to>workflow_timer</to>
- <condition>
- <name>Yes</name>
- <condition>activity.result == 'yes'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>workflow_timer</from>
- <to>retrieve_status</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>retrieve_status</from>
- <to>check_timeout</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_timeout</from>
- <to>workflow_timer</to>
- <condition>
- <name>No</name>
- <condition>activity.result == 'no'</condition>
- <order>2</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_timeout</from>
- <to>check_result</to>
- <condition>
- <name>Yes</name>
- <condition>activity.result == 'yes'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_result</from>
- <to>ended_failed</to>
- <condition>
- <name>No</name>
- <condition>activity.result == 'no'</condition>
- <order>2</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>ended_failed</from>
- <to>end</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>check_result</from>
- <to>ended_ok</to>
- <condition>
- <name>Yes</name>
- <condition>activity.result == 'yes'</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- <transition>
- <from>ended_ok</from>
- <to>end</to>
- <condition>
- <name>Always</name>
- <condition>true</condition>
- <order>1</order>
- <description/>
- </condition>
- </transition>
- </transitions>
- </workflow>
- </workflows>
- <fix_scripts>
- <fix_script>
- <name>Sara - Create Scheduler for auto-sync</name>
- <description>Create Scheduler for auto-sync service and lookup value</description>
- <active>true</active>
- <run_once>true</run_once>
- <script><![CDATA[var glideHelper = new x_ausgh_snsc.SaraGlideHelper();
- glideHelper.persistData(x_ausgh_snsc.SaraCommon.TABLE_NAME.SN_AUTO_SCRIPT, {
- 'name': 'SaraAutoSync',
- 'script': 'new x_ausgh_snsc.SaraSync().syncServices();',
- 'active': true,
- 'run_type': 'periodically',
- 'run_period': '02:00:00',
- 'sys_class_name': 'sysauto_script',
- 'run_dayofweek': 1
- });
- ]]></script>
- </fix_script>
- <fix_script>
- <name>Sara - Remove Scheduler for auto-sync</name>
- <description>Remove Scheduler for auto-sync service and lookup value</description>
- <active>true</active>
- <run_once>true</run_once>
- <script><![CDATA[var glideHelper = new x_ausgh_snsc.SaraGlideHelper();
- glideHelper.deleteData(x_ausgh_snsc.SaraCommon.TABLE_NAME.SN_AUTO_SCRIPT, {
- 'name': 'SaraAutoSync'
- }, true);
- ]]></script>
- </fix_script>
- </fix_scripts>
- <wizards>
- <wizard>
- <name>Automic OAuth Configuration</name>
- <type>expert</type>
- <banner_type>fixed</banner_type>
- <roles>admin</roles>
- <first_panel>OAuth Client</first_panel>
- <variables>
- <variable>
- <name>sara_client_scripts</name>
- <type>14</type>
- <class>expert_variable</class>
- <question>Sara Client Scripts</question>
- <order>0</order>
- <mandatory>false</mandatory>
- <active>true</active>
- <panel>Config OAuth Client</panel>
- <macro>sara_client_scripts</macro>
- </variable>
- <variable>
- <name>client_id</name>
- <type>6</type>
- <class>expert_variable</class>
- <question>Client ID</question>
- <order>100</order>
- <mandatory>true</mandatory>
- <active>true</active>
- <panel>Config OAuth Client</panel>
- </variable>
- <variable>
- <name>client_secret</name>
- <type>6</type>
- <class>expert_variable</class>
- <question>Client Secret</question>
- <order>200</order>
- <mandatory>true</mandatory>
- <active>true</active>
- <panel>Config OAuth Client</panel>
- </variable>
- <variable>
- <name>technical_user</name>
- <type>6</type>
- <class>expert_variable</class>
- <question>Technical User</question>
- <order>300</order>
- <mandatory>true</mandatory>
- <active>true</active>
- <panel>Config OAuth Client</panel>
- </variable>
- <variable>
- <name>sapi_endpoint</name>
- <type>6</type>
- <class>expert_variable</class>
- <question>SAPI Endpoint</question>
- <order>400</order>
- <mandatory>true</mandatory>
- <active>true</active>
- <panel>Config OAuth Client</panel>
- </variable>
- <variable>
- <name>token_endpoint</name>
- <type>6</type>
- <class>expert_variable</class>
- <question>Token Endpoint</question>
- <order>500</order>
- <mandatory>true</mandatory>
- <active>true</active>
- <panel>Config OAuth Client</panel>
- </variable>
- <variable>
- <name>auth_endpoint</name>
- <type>6</type>
- <class>expert_variable</class>
- <question>Authorization Endpoint</question>
- <order>600</order>
- <mandatory>true</mandatory>
- <active>true</active>
- <panel>Config OAuth Client</panel>
- </variable>
- </variables>
- <panels>
- <panel>
- <name>Config OAuth Client</name>
- <title>Config OAuth Client</title>
- <class>expert_panel</class>
- <description>Config OAuth Server Endpoints, Client ID, Client Secret, SAPI Endpoint and Technical User for SNSC. OAuth login popup will be shown in case Technical User doesn't have tokens or Technical User's tokens are empty, invalid or expired.</description>
- <previous_message>Previous</previous_message>
- <next_message>Store OAuth Client Settings</next_message>
- <complete_message>Done</complete_message>
- <client_script>
- <name>SARA OAuth Client OnLoad</name>
- <active>true</active>
- <type>onLoad</type>
- <script><![CDATA[function onLoad() {
- g_form.getControl(x_ausgh_snsc.SaraCommon.CONFIG_NAME.CLIENT_SECRET).type = 'password';
- x_ausgh_snsc.oldConfig = {};
- x_ausgh_snsc.SaraOAuth.getConfig(function (configData) {
- for (var name in configData) {
- var value = configData[name];
- g_form.setValue(name, value);
- x_ausgh_snsc.oldConfig[name] = value;
- }
- });
- }
- ]]></script>
- </client_script>
- <client_script>
- <name>SARA OAuth Client OnSubmit</name>
- <active>true</active>
- <type>onSubmit</type>
- <script><![CDATA[function onSubmit() {
- if (x_ausgh_snsc.isTokenValid) {
- return true;
- } else {
- var isChange = false;
- for (var name in x_ausgh_snsc.oldConfig) {
- if (x_ausgh_snsc.oldConfig[name] !== g_form.getValue(name).toString() && name !== x_ausgh_snsc.SaraCommon.CONFIG_NAME.SAPI_ENDPOINT) {
- isChange = true;
- break;
- }
- }
- if (isChange && !x_ausgh_snsc.notChange) {
- getToken();
- } else {
- // Clean all existing messages
- g_form.clearMessages();
- // Check if Sara tokens exist for Technical User
- var technicalUser = g_form.getValue(x_ausgh_snsc.SaraCommon.CONFIG_NAME.TECHNICAL_USER).toString();
- var sapiEndpoint = g_form.getValue(x_ausgh_snsc.SaraCommon.CONFIG_NAME.SAPI_ENDPOINT).toString();
- x_ausgh_snsc.SaraOAuth.checkOAuthToken(technicalUser, sapiEndpoint, false, {
- onValid: function () {
- x_ausgh_snsc.isTokenValid = true;
- g_expert.next();
- },
- onInvalid: function () {
- x_ausgh_snsc.isTokenValid = false;
- getToken();
- },
- onError: function (errorMessage) {
- x_ausgh_snsc.isTokenValid = false;
- g_form.addErrorMessage(errorMessage);
- }
- });
- }
- }
- return false;
- }
- function getToken() {
- x_ausgh_snsc.log('Preparing for openning OAuth login popup...');
- for (var key in x_ausgh_snsc.SaraCommon.CONFIG_NAME) {
- var name = x_ausgh_snsc.SaraCommon.CONFIG_NAME[key];
- x_ausgh_snsc.config[name] = g_form.getValue(name).toString();
- }
- x_ausgh_snsc.SaraOAuth.login(
- x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.CLIENT_ID],
- x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.TECHNICAL_USER],
- x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.AUTH_ENDPOINT], {
- onSuccess: function () {
- x_ausgh_snsc.notChange = true;
- g_expert.next();
- }
- }
- );
- }
- ]]></script>
- </client_script>
- </panel>
- <panel>
- <name>Config OAuth Client Completed</name>
- <title>Config OAuth Client Completed</title>
- <class>expert_panel</class>
- <description/>
- <previous_message>Previous</previous_message>
- <next_message>Next</next_message>
- <complete_message>Done</complete_message>
- </panel>
- </panels>
- <transitions>
- <transition>
- <from>Config OAuth Client</from>
- <to>Config OAuth Client Completed</to>
- <order>100</order>
- <condition/>
- <transition_script><![CDATA[var LOGGER = new x_ausgh_snsc.SaraLog('sara_oauth_client_transition');
- gs.addInfoMessage('Client ID = ' + wizard[x_ausgh_snsc.SaraCommon.CONFIG_NAME.CLIENT_ID]
- + ', Client Secret = ***'
- + ', Technical User = ' + wizard[x_ausgh_snsc.SaraCommon.CONFIG_NAME.TECHNICAL_USER]
- + ', SAPI Endpoint = ' + wizard[x_ausgh_snsc.SaraCommon.CONFIG_NAME.SAPI_ENDPOINT]
- + ', Token Endpoint = ' + wizard[x_ausgh_snsc.SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT]
- + ', Authorization Endpoint = ' + wizard[x_ausgh_snsc.SaraCommon.CONFIG_NAME.AUTH_ENDPOINT]);
- var saraConfig = new x_ausgh_snsc.SaraConfig();
- try {
- var configData = {};
- for (var key in x_ausgh_snsc.SaraCommon.CONFIG_NAME) {
- var name = x_ausgh_snsc.SaraCommon.CONFIG_NAME[key];
- configData[name] = wizard[name];
- }
- saraConfig.storeClientConfig(configData);
- LOGGER.info('OAuth Configuration updated:\n'
- + ' - Client ID = {0}, \n'
- + ' - Client Secret = ***, \n'
- + ' - Technical User = {1} \n'
- + ' - SAPI Endpoint = {2}, \n'
- + ' - Token Endpoint = {3}, \n'
- + ' - Authorization Endpoint = {4}',
- configData[x_ausgh_snsc.SaraCommon.CONFIG_NAME.CLIENT_ID],
- configData[x_ausgh_snsc.SaraCommon.CONFIG_NAME.TECHNICAL_USER],
- configData[x_ausgh_snsc.SaraCommon.CONFIG_NAME.SAPI_ENDPOINT],
- configData[x_ausgh_snsc.SaraCommon.CONFIG_NAME.TOKEN_ENDPOINT],
- configData[x_ausgh_snsc.SaraCommon.CONFIG_NAME.AUTH_ENDPOINT]
- );
- gs.addInfoMessage('Successfully update Automic OAuth client settings');
- } catch (err) {
- LOGGER.info('Error on update Automic OAuth client settings: {0}', err);
- gs.addInfoMessage('Failed to update Automic OAuth client settings');
- }
- ]]></transition_script>
- </transition>
- </transitions>
- </wizard>
- <wizard>
- <name>Automic Import Services</name>
- <type>expert</type>
- <banner_type>fixed</banner_type>
- <roles>admin</roles>
- <first_panel>Import Services</first_panel>
- <variables>
- <variable>
- <name>sara_client_scripts</name>
- <type>14</type>
- <class>expert_variable</class>
- <question>Sara Client Scripts</question>
- <order>0</order>
- <mandatory>false</mandatory>
- <active>true</active>
- <panel>Import Services</panel>
- <macro>sara_client_scripts</macro>
- </variable>
- <variable>
- <name>sara_message</name>
- <type>6</type>
- <class>expert_variable</class>
- <question>Sara Message</question>
- <order>100</order>
- <mandatory>false</mandatory>
- <active>true</active>
- <panel>Import Services</panel>
- </variable>
- <variable>
- <name>sara_target_category</name>
- <type>18</type>
- <class>expert_variable</class>
- <question>Select Target Category</question>
- <order>200</order>
- <mandatory>true</mandatory>
- <active>true</active>
- <lookup_table>sc_category</lookup_table>
- <lookup_value>sys_id</lookup_value>
- <lookup_label>title</lookup_label>
- <panel>Import Services</panel>
- </variable>
- </variables>
- <panels>
- <panel>
- <name>Import Services</name>
- <title>Import Services</title>
- <class>expert_panel</class>
- <description>Import SARA services to Service Catalog. Error messages will be shown in case Technical User doesn't have tokens or Technical User's tokens empty, invalid or expired.</description>
- <previous_message>Previous</previous_message>
- <next_message>Import Services</next_message>
- <complete_message>Done</complete_message>
- <client_script>
- <name>Import Services OnLoad</name>
- <active>true</active>
- <type>onLoad</type>
- <script><![CDATA[function onLoad() {
- x_ausgh_snsc.SaraUtils.setFormControlVisible('sara_message', false);
- x_ausgh_snsc.SaraUtils.setWizardSubmitVisible(false);
- x_ausgh_snsc.SaraOAuth.getConfig(function (configData) {
- for (var key in configData) {
- var value = configData[key];
- x_ausgh_snsc.config[key] = value;
- if (!value) {
- g_form.addErrorMessage('OAuth Configuration "' + key + '" is empty. Please check the current OAuth configuration.');
- x_ausgh_snsc.SaraUtils.setWizardSubmitVisible(false);
- break;
- }
- }
- setTimeout(function () {
- checkToken();
- }, 100);
- });
- }
- function checkToken() {
- var technicalUser = x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.TECHNICAL_USER];
- var sapiEndpoint = x_ausgh_snsc.config[x_ausgh_snsc.SaraCommon.CONFIG_NAME.SAPI_ENDPOINT];
- x_ausgh_snsc.SaraOAuth.checkOAuthToken(technicalUser, sapiEndpoint, true, {
- onValid: function () {
- x_ausgh_snsc.SaraUtils.setWizardSubmitVisible(true);
- },
- onInvalid: function () {
- g_form.addErrorMessage('Tokens are empty, invalid or expired! Please contact your administrator for resolving this problem.');
- },
- onError: function (errorMessage) {
- g_form.addErrorMessage(errorMessage);
- }
- });
- }
- ]]></script>
- </client_script>
- <client_script>
- <name>Import Services OnSubmit</name>
- <active>true</active>
- <type>onSubmit</type>
- <script><![CDATA[function onSubmit() {
- if (x_ausgh_snsc.isOk) {
- return true;
- }
- var importDialog = new GlideDialogWindow('hierarchical_progress_viewer');
- importDialog.setPreference('sysparm_ajax_processor', 'x_ausgh_snsc.SaraConsumerRunner');
- importDialog.setPreference('sysparm_catid', g_form.getValue('sara_target_category').toString());
- importDialog.setSize(400, 300);
- importDialog.setTitle('Importing service...');
- importDialog.on('executionComplete', function (trackerObj) {
- x_ausgh_snsc.log('executionComplete', trackerObj);
- if (trackerObj.result && trackerObj.result.info) {
- importDialog.setTitle(trackerObj.result.msg);
- g_form.setValue('sara_message', trackerObj.result.info);
- x_ausgh_snsc.isOk = true;
- x_ausgh_snsc.log('Go to next panel', x_ausgh_snsc.isOk);
- g_expert.next();
- x_ausgh_snsc.log('Destroy diablog', importDialog);
- importDialog.destroy();
- }
- });
- importDialog.on("renderStatus", function (trackerObj) {
- x_ausgh_snsc.log('renderStatus', trackerObj);
- if (trackerObj && trackerObj.result && trackerObj.result.msg) {
- importDialog.setTitle(trackerObj.result.msg);
- }
- });
- // Render the viewer
- importDialog.render();
- return false;
- }
- ]]></script>
- </client_script>
- </panel>
- <panel>
- <name>Import Services Completed</name>
- <title>Import Services Completed</title>
- <class>expert_panel</class>
- <description/>
- <previous_message>Previous</previous_message>
- <next_message>Next</next_message>
- <complete_message>Done</complete_message>
- </panel>
- </panels>
- <transitions>
- <transition>
- <from>Import Services</from>
- <to>Import Services Completed</to>
- <order>100</order>
- <condition>[sara_target_category]!=^EQ</condition>
- <transition_script><![CDATA[gs.addInfoMessage(wizard.sara_message.toString());
- ]]></transition_script>
- </transition>
- </transitions>
- </wizard>
- <wizard>
- <name>Automic Clean-up</name>
- <type>expert</type>
- <banner_type>fixed</banner_type>
- <roles>admin</roles>
- <first_panel>Automic Cleanup</first_panel>
- <variables>
- <variable/>
- </variables>
- <panels>
- <panel>
- <name>Cleanup Catalog Items</name>
- <title>Cleanup Catalog Items</title>
- <class>expert_panel</class>
- <description>Cleanup all Automic SARA stuffs. This will delete all subcategories and service items.</description>
- <previous_message>Previous</previous_message>
- <next_message>Cleanup</next_message>
- <complete_message>Done</complete_message>
- </panel>
- <panel>
- <name>Cleanup Catalog Items Completed</name>
- <title>Cleanup Catalog Items Completed</title>
- <class>expert_panel</class>
- <description>Cleanup successfully!</description>
- <previous_message>Previous</previous_message>
- <next_message>Next</next_message>
- <complete_message>Done</complete_message>
- </panel>
- </panels>
- <transitions>
- <transition>
- <from>Cleanup Catalog Items</from>
- <to>Cleanup Catalog Items Completed</to>
- <order>100</order>
- <condition/>
- <transition_script>
- <![CDATA[x_ausgh_snsc.SaraUtils.cleanup();]]>
- </transition_script>
- </transition>
- </transitions>
- </wizard>
- </wizards>
- <processors>
- <processor>
- <name>SaraUpdateStatus</name>
- <type>script</type>
- <active>true</active>
- <description>Sara REST api for updating status of worflow remotely</description>
- <path>sara_update_status</path>
- <script><![CDATA[var LOGGER = new x_ausgh_snsc.SaraLog('SaraUpdateStatus');
- var runId = g_request.getParameter('runId');
- var status = g_request.getParameter('status');
- var error = 0;
- var result = {};
- LOGGER.info('SaraUpdateStatus: RunId = {0}, Status = {1}', runId, status);
- LOGGER.info('SaraUpdateStatus: Request user = ' + gs.getUserName());
- if (!runId) {
- error += 1;
- }
- if (!status) {
- error += 1;
- }
- if (error === 0) {
- runId = +runId;
- if (isNaN(runId)) {
- result = {
- code: 99,
- message: 'The runId must be digits!'
- };
- } else {
- var glideHelper = new x_ausgh_snsc.SaraGlideHelper();
- var reqItem = glideHelper.getData('sc_req_item', {
- 'correlation_id': runId.toString()
- });
- if (reqItem) {
- LOGGER.info('Found current request item (correlation_id = {0}, sys_id = {1})', runId, reqItem['sys_id']);
- try {
- glideHelper.updateData('sc_req_item', {
- 'sys_id': reqItem['sys_id']
- }, {
- 'comments': status,
- 'display_state': status
- });
- result = {
- code: 200,
- message: 'Update OK!',
- sysId: reqItem['sys_id']
- };
- } catch (e) {
- result = {
- code: 99,
- message: err
- };
- }
- } else {
- var message = x_ausgh_snsc.SaraUtils.formatString('No request item (correlation_id = {0}) found! Update status failed.', runId);
- LOGGER.info(message);
- result = {
- code: 99,
- message: message
- };
- }
- }
- } else {
- result = {
- code: 99,
- message: 'The runId and status must be not null!'
- }
- }
- var response = x_ausgh_snsc.SaraJSON.stringify(result);
- LOGGER.debug('SaraUpdateStatus: {0}', response);
- g_processor.writeOutput('application/json', response);
- ]]></script>
- </processor>
- </processors>
- <snsc_application>
- <application>
- <name>Automic SNSC</name>
- <short_description>Automic ServiceNow Service Connector Application</short_description>
- <active>true</active>
- <user_role>x_ausgh_snsc.user</user_role>
- <version>1.0.2</version>
- <menu>u_ausgh_snsc_menu</menu>
- <scope>x_ausgh_snsc</scope>
- </application>
- <application_menu>
- <name>u_ausgh_snsc_menu</name>
- <active>true</active>
- <category>Custom Applications</category>
- <title>Automic SNSC</title>
- <roles>x_ausgh_snsc.user</roles>
- <hint>Automic ServiceNow Service Connector Application</hint>
- </application_menu>
- <user_role>
- <name>x_ausgh_snsc.user</name>
- <description>User role for SNSC application</description>
- </user_role>
- </snsc_application>
- <modules>
- <module>
- <title>Automic Configuration</title>
- <order>0</order>
- <active>true</active>
- <link_type>SEPARATOR</link_type>
- </module>
- <module>
- <title>Automic Clean-up</title>
- <reference>wizard</reference>
- <reference_name>Automic Clean-up</reference_name>
- <order>10</order>
- <active>true</active>
- <link_type>DIRECT</link_type>
- <query>/expert_shell.do?sysparm_sys_id=@{sys_id}&sysparm_initial=true</query>
- </module>
- <module>
- <title>Automic Import Services</title>
- <reference>wizard</reference>
- <reference_name>Automic Import Services</reference_name>
- <order>20</order>
- <active>true</active>
- <link_type>DIRECT</link_type>
- <query>/expert_shell.do?sysparm_sys_id=@{sys_id}&sysparm_initial=true</query>
- </module>
- <module>
- <title>Automic OAuth Configuration</title>
- <reference>wizard</reference>
- <reference_name>Automic OAuth Configuration</reference_name>
- <order>30</order>
- <active>true</active>
- <link_type>DIRECT</link_type>
- <query>/expert_shell.do?sysparm_sys_id=@{sys_id}&sysparm_initial=true</query>
- </module>
- <module>
- <title>Automic SNSC Components</title>
- <order>100</order>
- <active>true</active>
- <link_type>SEPARATOR</link_type>
- </module>
- <module>
- <title>Sara Tables</title>
- <order>110</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_db_object</table_name>
- <filter>nameSTARTSWITHx_ausgh_snsc_</filter>
- </module>
- <module>
- <title>Sara Transform Maps</title>
- <order>115</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_transform_map</table_name>
- <filter>nameSTARTSWITHx_ausgh_snsc_</filter>
- </module>
- <module>
- <title>Sara System Properties</title>
- <reference>system_property</reference>
- <reference_name>Automic</reference_name>
- <order>120</order>
- <active>true</active>
- <link_type>DIRECT</link_type>
- <query>/sys_properties_category.do?sys_id=@{sys_id}</query>
- </module>
- <module>
- <title>Sara Script Includes</title>
- <order>130</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_script_include</table_name>
- <filter>nameSTARTSWITHSara</filter>
- </module>
- <module>
- <title>Sara UI Scripts</title>
- <order>140</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_ui_script</table_name>
- <filter>nameSTARTSWITHx_ausgh_snsc.Sara</filter>
- </module>
- <module>
- <title>Sara Fix Scripts</title>
- <order>140</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_script_fix</table_name>
- <filter>nameSTARTSWITHSara</filter>
- </module>
- <module>
- <title>Sara UI Pages</title>
- <order>150</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_ui_page</table_name>
- <filter>nameSTARTSWITHsara_</filter>
- </module>
- <module>
- <title>Sara UI Macros</title>
- <order>160</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_ui_macro</table_name>
- <filter>nameSTARTSWITHsara_</filter>
- </module>
- <module>
- <title>Sara Processors</title>
- <order>170</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_processor</table_name>
- <filter>nameSTARTSWITHSara</filter>
- </module>
- <module>
- <title>Sara Wizards</title>
- <order>180</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>expert</table_name>
- <filter>nameSTARTSWITHAutomic</filter>
- </module>
- <module>
- <title>Sara Schedulers</title>
- <order>190</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sysauto</table_name>
- <filter>nameSTARTSWITHSara</filter>
- </module>
- <module>
- <title>Sara REST Messages</title>
- <order>200</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_rest_message</table_name>
- <filter>nameSTARTSWITHSara</filter>
- </module>
- <module>
- <title>Support</title>
- <order>900</order>
- <active>true</active>
- <link_type>SEPARATOR</link_type>
- </module>
- <module>
- <title>Used ServiceNow's Tables</title>
- <order>910</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_db_object</table_name>
- <query>name=sc_category^ORname=sc_cat_item^ORname=item_option_new_set^ORname=io_set_item^ORname=sysauto_script^ORname=item_option_new</query>
- </module>
- <module>
- <title>Sara Transform History</title>
- <order>915</order>
- <active>true</active>
- <link_type>LIST</link_type>
- <table_name>sys_import_set_run</table_name>
- <query>sys_transform_mapSTARTSWITHx_ausgh_snsc</query>
- </module>
- <module>
- <title>Contact Us</title>
- <order>920</order>
- <active>true</active>
- <link_type>DIRECT</link_type>
- <query>https://automationpassion.com/contact_us.do</query>
- </module>
- </modules>
- <rest_messages>
- <rest_message>
- <name>Sara - SAPI Services</name>
- <description>Sara Outbound Web Service for SAPI</description>
- <rest_endpoint>${sapiEndpoint}</rest_endpoint>
- </rest_message>
- <rest_message>
- <name>Sara - OAuth Services</name>
- <description>Sara Outbound Web Service for OAuth</description>
- <rest_endpoint>${oauthEndpoint}</rest_endpoint>
- </rest_message>
- </rest_messages>
- </package>
- </sara>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement