Skip to content

Instantly share code, notes, and snippets.

@thisnameissoclever
Last active March 28, 2024 09:46
Show Gist options
  • Save thisnameissoclever/47e0b9a9543d9138faa89b1c0a7918e7 to your computer and use it in GitHub Desktop.
Save thisnameissoclever/47e0b9a9543d9138faa89b1c0a7918e7 to your computer and use it in GitHub Desktop.
ServiceNow Local System Properties
/**
* Local (instance-specific) System Property Script Include
* More info available at https://localprop.snc.guru
*
* A ServiceNow JavaScript ES5 class, LocalProperty, for getting and setting instance-specific
* system properties.
* See method documentation for more information.
* @param {string} [instanceNameOverride=] - Override the name of the instance that's currently
* executing this code.
* For example, if you have a system property such as "my_prod_instance.some_property" which
* you need to specifically retrieve while executing code in your development environment
* for some reason, you would call this constructor like so: <br />
*
* var localPropUtil = new LocalProperty('my_prod_instance');
* //...
*
* This is most commonly useful for testing, but this argument should generally NOT be specified.
*
* @constructor
*/
function LocalProperty(instanceNameOverride) {
//If the instance name override is not provided, use the instance name system property.
var instanceNamePropVal = gs.getProperty('instance_name', '');
//Set the local-scope instance_name property for later use, depending on whether the override argument has been specified.
this.instance_name = (typeof instanceNameOverride === 'undefined') ?
(instanceNamePropVal) : (instanceNameOverride);
//If the instance name is empty, throw an error.
//This should never happen, and would indicate that something has gone horribly wrong.
if (!this.instance_name) {
throw new Error(
'Whoa there! The "instance_name" system property was not found in the sys_properties ' +
'table. Please set the instance_name property. This is very important, not just ' +
'for this specific error!'
);
}
/* Methods below */
/**
* Get the value of an instance-specific ("local") system property.
* Local system properties should follow the pattern <instance_name>.<property_name>. For
* example, if your instance is named "my_instance" and you want to retrieve the value of a
* property named "my_http_endpoint", you would need to have a system property with the
* name "my_instance.my_http_endpoint", and call this method with the propVal argument
* "my_http_endpoint".
*
* @param {string} propName - The name suffix of the system property to retrieve.
* This should be the portion of the system property name that comes after the instance name.
* For example, if your instance name is "dev1234", and you want to retrieve the value of a
* system property named "dev1234.my_http_endpoint", you would pass "my_http_endpoint" as
* the propName argument and not include the instance name in this argument.
* If there is no system property with the name <instance_name>.<propName>, then the default value you specify in the defaultVal argument is returned. If you do not specify a default value, then an empty string is returned instead.
* The instance name is retrieved automatically from the instance_name system property, but can be overridden when calling the constructor for this class.
*
* @param {string} [defaultVal=''] - The default value to return if the system property
* is not found.
*
* @returns {string} - The value of the system property with the name
* <instance_name>.<propName>, or the default value if the system property is not found.
*
* @example Get the value of a local system property "my_instance.my_http_endpoint":
* var propName = 'my_http_endpoint';
* var localProp = new LocalProperty();
* var propVal = localProp.getProperty(propName);
*
* @example Get the value of a local system property "my_instance.my_http_endpoint", but with a default value of "http://localhost:8080":
* var propName = 'my_http_endpoint';
* var defaultVal = 'http://localhost:8080';
* var localProp = new LocalProperty();
* var propVal = localProp.getProperty(propName, defaultVal);
*
* @example Get the value of a local system property "my_other_instance.my_http_endpoint", but with a default value of "http://localhost:8080", and override the instance name (in this case, to "my_other_instance") - which will cause the system property "my_other_instance.my_http_endpoint" to be retrieved no matter which instance this code is executed in:
* var propName = 'my_http_endpoint';
* var defaultVal = 'http://localhost:8080';
* var instanceNameOverride = 'my_other_instance';
* var localProp = new LocalProperty(instanceNameOverride);
* var propVal = localProp.getProperty(propName, defaultVal);
*/
this.getProperty = function(propName, defaultVal) {
var propVal;
var fullPropName = this.instance_name + '.' + propName;
//Set the default value ('') of the defaultVal argument if it is not provided.
defaultVal = (typeof defaultVal === 'undefined') ? ('') : (defaultVal);
//If the propName argument is not provided, throw an error.
if (!propName) {
throw new Error(
'Whoa there! The "propName" argument was not provided when attempting to get a ' +
'property with the LocalProperty class. You must provide a value for the propName ' +
'argument.'
);
}
//Get the value of the system property with the naming pattern <instance_name>.<propName>.
propVal = gs.getProperty(
fullPropName,
defaultVal
);
gs.debug(
'Got the value "' + propVal + '" from system property with name "' +
fullPropName + '".'
);
return propVal;
};
/**
* Set the value of an instance-specific ("local") system property to the specified new value.
* Local system properties should follow the pattern <instance_name>.<property_name>. For
* example, if your instance is named "my_instance" and you want to set the value of a
* property named "my_http_endpoint", you would need to have a system property with the
* name "my_instance.my_http_endpoint", and call this method with the propVal argument
* "my_http_endpoint".
*
* Note: Care should be taken when setting system properties (sys_properties), as it causes
* a system-wide cache flush. Each flush can cause system degradation while the caches
* rebuild. If a value must be updated often, it should not be stored as a system property.
* In general, you should only place values in the sys_properties table that do not
* frequently change.
*
* Note: Just as with using the OOB gs.setProperty() method, if the specified system property does not exist, then it will be created. If it is created, it will always be created as a STRING type -- regardless of what data-type is passed into it. Therefore,
*
* @param {string} propName - The name suffix of the system property to set.
* This should be the portion of the system property name that comes after the instance name.
* For example, if your instance name is "dev1234", and you want to set the value of a
* system property named "dev1234.my_http_endpoint", you would pass "my_http_endpoint" as
* the propName argument and not include the instance name in this argument.
* If there is no system property with the name <instance_name>.<propName>, then the default
* value you specify in the defaultVal argument is returned. If you do not specify a default
* value, then an empty string is returned instead.
* The instance name is retrieved automatically from the instance_name system property, but
* can be overridden when calling the constructor for this class.
*
* @param {string} [newVal=''] - The new value to which the specified system property should
* be set.
* If this is not specified, then the system property will be set to a blank string.
* If the system property does not exist, then it will be created.
*
* @param {string} [description=] - A description of the property.
* This can normally be left blank unless you're intending to create a new system property,
* but is not mandatory in either case.
*
* @returns {string} the new value to which the specified system property has been set.
*
* @example Set the value of a local system property "my_instance.my_http_endpoint" to the new value http://localhost:8080 (if the property doesn't exist, it will be created):
* var propName = 'my_http_endpoint';
* var newPropVal = 'http://localhost:8080';
* var localProp = new LocalProperty();
*
* localProp.setProperty(propName, newPropVal);
*
* @example Set the value of a local system property "my_other_instance.my_http_endpoint" to "http://localhost:8080", but override the instance name (in this case, to "my_other_instance") - which will cause the system property "my_other_instance.my_http_endpoint" to be set no matter which instance this code is executed in:
* var propName = 'my_http_endpoint';
* var newPropVal = 'http://localhost:8080';
* var instanceNameOverride = 'my_other_instance';
* var localProp = new LocalProperty(instanceNameOverride);
* localProp.setProperty(propName, defaultVal);
*/
this.setProperty = function(propName, newVal, description) {
var fullPropName;
if (!propName) {
throw new Error(
'Whoa there! The "propName" argument was not provided when attempting to set a ' +
'property with the LocalProperty class. You must provide a value for the ' +
'propName argument.'
);
}
fullPropName = this.instance_name + '.' + propName;
if (typeof newVal === 'undefined') {
gs.warn(
'The "newVal" argument was not provided when attempting to set the value ' +
'of the property "' + fullPropName + '" with the LocalProperty class. The ' +
'property will be set to an empty string. \n' +
'It is best to explicitly pass an empty string to this method if that is the ' +
'desired outcome.'
);
newVal = '';
}
gs.debug(
'Setting the system property "' + fullPropName + '" to the new value "' +
newVal + '".'
);
if (description) {
gs.setProperty(
fullPropName,
newVal,
description
);
return newVal;
}
gs.setProperty(
fullPropName,
newVal
);
return newVal;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment