Skip to content

Commit

Permalink
ISPN-13218 improve error message
Browse files Browse the repository at this point in the history
  • Loading branch information
karesti committed Aug 5, 2021
1 parent ef19ee0 commit 5eb8409
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 25 deletions.
8 changes: 8 additions & 0 deletions src/__tests__/services/cacheConfigUtils.test.ts
Expand Up @@ -119,4 +119,12 @@ describe('Cache Config Utils tests', () => {
]);
});

test('minim validation of the configuration json or xml', () => {
expect(CacheConfigUtils.validateConfig('').isLeft()).toBeTruthy();
expect(CacheConfigUtils.validateConfig(' ').isLeft()).toBeTruthy();
expect(CacheConfigUtils.validateConfig('xml').isLeft()).toBeTruthy();
expect(CacheConfigUtils.validateConfig('json').isLeft()).toBeTruthy();
expect(CacheConfigUtils.validateConfig('{}').isRight()).toBeTruthy();
expect(CacheConfigUtils.validateConfig('<xml>foo</xml>').isRight()).toBeTruthy();
});
});
45 changes: 20 additions & 25 deletions src/app/Caches/CreateCache.tsx
Expand Up @@ -29,6 +29,7 @@ import {useHistory} from 'react-router';
import {useApiAlert} from '@app/utils/useApiAlert';
import {DataContainerBreadcrumb} from '@app/Common/DataContainerBreadcrumb';
import {ConsoleServices} from "@services/ConsoleServices";
import {CacheConfigUtils} from "@services/cacheConfigUtils";

const CreateCache: React.FunctionComponent<any> = (props) => {
const { addAlert } = useApiAlert();
Expand All @@ -47,6 +48,7 @@ const CreateCache: React.FunctionComponent<any> = (props) => {
const [validConfig, setValidConfig] = useState<
'success' | 'error' | 'default'
>('default');
const [errorConfig, setErrorConfig] = useState('');

interface OptionSelect {
value: string;
Expand Down Expand Up @@ -103,39 +105,31 @@ const CreateCache: React.FunctionComponent<any> = (props) => {
}
};

const validateConfig = (): boolean => {
const trimmedConf = config.trim();
if (trimmedConf.length == 0) {
return false;
}
let isJson = false;
let isXML = false;
try {
JSON.parse(trimmedConf);
isJson = true;
} catch (ex) {}

try {
let oDOM = new DOMParser().parseFromString(trimmedConf, 'text/xml');
if (oDOM.getElementsByTagName('parsererror').length == 0) {
isXML = true;
}
} catch (ex) {}
return isJson || isXML;
};

const createCache = () => {
setErrorConfig('');
const name = cacheName.trim();
// Validate Name
let isValidName: 'success' | 'error' =
name.length > 0 ? 'success' : 'error';
let isValidConfig: 'success' | 'error' =
selectedConfig != '' || validateConfig() ? 'success' : 'error';
setValidName(isValidName);

// Validate the config
let isValidConfig: 'success' | 'error' = 'error';
if (selectedConfig != '') {
isValidConfig = 'success';
} else {
let configValidation = CacheConfigUtils.validateConfig(config);
isValidConfig = configValidation.isRight() ? 'success' : 'error';
if (configValidation.isLeft()) {
setErrorConfig(configValidation.value);
}
}
setValidConfig(isValidConfig);

if (isValidName == 'error' || isValidConfig == 'error') {
return;
}

let createCacheCall: Promise<ActionResponse>;
if (selectedConfig != '') {
createCacheCall = ConsoleServices.caches().createCacheByConfigName(
Expand Down Expand Up @@ -202,9 +196,9 @@ const CreateCache: React.FunctionComponent<any> = (props) => {
<FormGroup
fieldId="cache-config-name"
label="Cache templates"
helperText="Select a cache template or provide a cache configuration."
helperText="Select a cache template or provide a valid cache configuration."
validated={validConfig}
helperTextInvalid="Your cache must have a configuration."
helperTextInvalid={errorConfig}
>
<Select
toggleIcon={<CubeIcon />}
Expand Down Expand Up @@ -238,6 +232,7 @@ const CreateCache: React.FunctionComponent<any> = (props) => {
<FormGroup
label="Cache configuration"
fieldId="cache-config"
validated={validConfig}
helperText="Enter a cache configuration in XML or JSON format."
helperTextInvalid="Provide a valid cache configuration in XML or JSON format."
>
Expand Down
28 changes: 28 additions & 0 deletions src/services/cacheConfigUtils.ts
@@ -1,4 +1,5 @@
import { ContentType, EncodingType } from '@services/infinispanRefData';
import {Either, left, right} from "@services/either";

export const Distributed = 'distributed-cache';
export const Replicated = 'replicated-cache';
Expand All @@ -10,6 +11,33 @@ export const Scattered = 'scattered-cache';
* Utility class to map cache configuration
*/
export class CacheConfigUtils {

/**
* Validates a configuration of cache may have a correct format and detects if it's
* a valid formatted json or a xml.
*
* @param config
*/
public static validateConfig (config: string): Either<string, 'xml' | 'json'> {
const trimmedConf = config.trim();

if (trimmedConf.length == 0) {
return left('Configuration can\'t be empty');
}
try {
JSON.parse(trimmedConf);
return right('json');
} catch (ex) {}

try {
let oDOM = new DOMParser().parseFromString(trimmedConf, 'text/xml');
if (oDOM.getElementsByTagName('parsererror').length == 0) {
return right('xml');
}
} catch (ex) {}
return left('The provided configuration is not a valid XML or JSON.');
};

/**
* Map the encoding type of the cache
* @param config, config of the cache
Expand Down

0 comments on commit 5eb8409

Please sign in to comment.