Skip to content

Commit

Permalink
ISPN-11492 and ISPN-11491 Cluster and Cache enable/disable rebalancing
Browse files Browse the repository at this point in the history
  • Loading branch information
karesti committed Sep 17, 2021
1 parent 8a86596 commit 7716e6c
Show file tree
Hide file tree
Showing 13 changed files with 254 additions and 45 deletions.
2 changes: 2 additions & 0 deletions src/app/CacheManagers/CacheManagers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {useTranslation} from 'react-i18next';
import {useConnectedUser} from "@app/services/userManagementHook";
import {ConsoleServices} from "@services/ConsoleServices";
import {ConsoleACL} from "@services/securityService";
import {RebalancingCacheManager} from "@app/CacheManagers/RebalancingCacheManager";

const CacheManagers = () => {
const { connectedUser } = useConnectedUser();
Expand Down Expand Up @@ -207,6 +208,7 @@ const CacheManagers = () => {
<Status status={cm.cache_manager_status} />
</FlexItem>
{buildSiteDisplay(cm.local_site)}
<RebalancingCacheManager/>
</Flex>
</Flex>
{buildTabs()}
Expand Down
51 changes: 51 additions & 0 deletions src/app/CacheManagers/RebalancingCacheManager.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import {Divider, FlexItem, Spinner, Switch} from '@patternfly/react-core';
import {useConnectedUser} from "@app/services/userManagementHook";
import {ConsoleServices} from "@services/ConsoleServices";
import {ConsoleACL} from "@services/securityService";
import {useTranslation} from "react-i18next";
import {useApiAlert} from "@app/utils/useApiAlert";
import {useDataContainer} from "@app/services/dataContainerHooks";

const RebalancingCacheManager = () => {
const { addAlert } = useApiAlert();
const { t } = useTranslation();
const { connectedUser } = useConnectedUser();
const { cm, loading, reload } = useDataContainer();

if (loading || !cm) {
return (
<FlexItem>
<Spinner size={'md'} />
</FlexItem>
);
}

if (ConsoleServices.security().hasConsoleACL(ConsoleACL.ADMIN, connectedUser)) {
return (
<React.Fragment>
<Divider isVertical />
<FlexItem>
<Switch
id="rebalancing-switch"
label={t('cache-managers.rebalancing-enabled')}
labelOff={t('cache-managers.rebalancing-disabled')}
isChecked={cm.rebalancing_enabled}
onChange={() => {
ConsoleServices.dataContainer().rebalancing(cm.name, !cm.rebalancing_enabled)
.then(r => {
addAlert(r);
reload();
})
}}
/>
</FlexItem>
</React.Fragment>
);
}

// Return nothing if the connected user is not ADMIN
return (<FlexItem></FlexItem>);
};

export { RebalancingCacheManager };
34 changes: 21 additions & 13 deletions src/app/Caches/DetailCache.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {ConsoleServices} from "@services/ConsoleServices";
import {ConsoleACL} from "@services/securityService";
import {useConnectedUser} from "@app/services/userManagementHook";
import {useTranslation} from "react-i18next";
import {RebalancingCache} from "@app/Caches/RebalancingCache";

const DetailCache = (props: { cacheName: string }) => {
const cacheName = props.cacheName;
Expand Down Expand Up @@ -104,17 +105,7 @@ const DetailCache = (props: { cacheName: string }) => {
};

const buildDetailContent = () => {
if (loading) {
return (
<Card>
<CardBody>
<Spinner size="xl" />
</CardBody>
</Card>
);
}

if (error.length > 0 || !cache) {
if (error.length > 0) {
return (
<Card>
<CardBody>
Expand Down Expand Up @@ -142,6 +133,16 @@ const DetailCache = (props: { cacheName: string }) => {
);
}

if (loading || !cache) {
return (
<Card>
<CardBody>
<Spinner size="xl" />
</CardBody>
</Card>
);
}

if(activeTabKey1 == 0
&& cache.editable
&& ConsoleServices.security().hasCacheConsoleACL(ConsoleACL.READ, cacheName, connectedUser)) {
Expand All @@ -162,6 +163,8 @@ const DetailCache = (props: { cacheName: string }) => {
};

const buildRebalancing = () => {
if (!cache) return ;

if (!cache?.rehash_in_progress) {
return (
<ToolbarItem>
Expand Down Expand Up @@ -308,7 +311,7 @@ const DetailCache = (props: { cacheName: string }) => {
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup>
{buildRebalancing()}
<RebalancingCache/>
{buildBackupsManage()}
{buildIndexManage()}
</ToolbarGroup>
Expand Down Expand Up @@ -416,7 +419,12 @@ const DetailCache = (props: { cacheName: string }) => {
activeKey={activeTabKey1}
isSecondary={true}
component={TabsComponent.nav}
onSelect={(event, tabIndex) => setActiveTabKey1(tabIndex)}
onSelect={(event, tabIndex) => {
setActiveTabKey1(tabIndex);
if (tabIndex == 0) {
loadCache(cacheName);
}
}}
>
{displayCacheEntries()}
{displayConfiguration()}
Expand Down
71 changes: 71 additions & 0 deletions src/app/Caches/RebalancingCache.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import {Label, Spinner, Switch, ToolbarItem} from '@patternfly/react-core';
import {useCacheDetail} from "@app/services/cachesHook";
import {useConnectedUser} from "@app/services/userManagementHook";
import {ConsoleServices} from "@services/ConsoleServices";
import {ConsoleACL} from "@services/securityService";
import {useTranslation} from "react-i18next";
import {useApiAlert} from "@app/utils/useApiAlert";
import {useDataContainer} from "@app/services/dataContainerHooks";

const RebalancingCache = () => {
const { addAlert } = useApiAlert();
const { t } = useTranslation();
const { connectedUser } = useConnectedUser();
const { cache, cacheManager, loading, reload } = useCacheDetail();

// If rebalancing is not activated at cluster level, don't display anything
if (!cacheManager.rebalancing_enabled) {
return ( <ToolbarItem/>)
}

if (loading || !cache) {
return (
<ToolbarItem>
<Spinner size={'md'} />
</ToolbarItem>
);
}

/**
* When the rehash is in progress just display the value
*/
if (cache?.rehash_in_progress) {
return (
<ToolbarItem>
<Spinner size={'md'} /> {t('caches.info.rebalancing')}
</ToolbarItem>
);
}

/**
* If the user is ADMIN, can enable and disable rebalancing
*/
if (ConsoleServices.security().hasConsoleACL(ConsoleACL.ADMIN, connectedUser)) {
return (
<ToolbarItem>
<Switch
id="rebalancing-switch"
label={t('caches.info.rebalancing-enabled')}
labelOff={t('caches.info.rebalancing-disabled')}
isChecked={cache.rebalancing_enabled}
onChange={() => {
ConsoleServices.caches().rebalancing(cache.name, !cache.rebalancing_enabled)
.then(r => {
addAlert(r);
reload();
})
}}
/>
</ToolbarItem>
);
}

return (
<ToolbarItem>
<Label>{t('caches.info.rebalanced')}</Label>
</ToolbarItem>
);
};

export { RebalancingCache };
7 changes: 5 additions & 2 deletions src/app/assets/languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@
"allowed-role" : "Allowed role",
"allowed-role-null" : "-",
"no-tasks-status" : "No tasks yet",
"no-tasks-body" : "Create tasks with the CLI or a remote client."
"no-tasks-body" : "Create tasks with the CLI or a remote client.",
"rebalancing-enabled": "Rebalancing is on",
"rebalancing-disabled": "Rebalancing is off"
},
"caches" : {
"configuration" : {
Expand All @@ -129,7 +131,8 @@
"loading" : "Loading cache {{cacheName}} ...",
"error" : "An error occurred while loading {{cacheName}}",
"rebalanced" : "Rebalanced",
"rebalancing" : "Rebalancing"
"rebalancing-enabled" : "Rebalancing is on",
"rebalancing-disabled" : "Rebalancing is off"
},
"actions" : {
"action-see-less" : "See fewer cache details",
Expand Down
40 changes: 27 additions & 13 deletions src/app/providers/CacheDetailProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {ContentType} from "@services/infinispanRefData";
const initialContext = {
error: '',
loading: false,
cacheManager: (undefined as unknown) as CacheManager,
cache: (undefined as unknown) as DetailedInfinispanCache,
loadCache: (name: string) => {},
reload: () => {},
Expand All @@ -23,6 +24,9 @@ export const CacheDetailContext = React.createContext(initialContext);
const CacheDetailProvider = ({ children }) => {
const {connectedUser} = useConnectedUser();
const [cacheName, setCacheName] = useState('');
const [cacheManager, setCacheManager] = useState<CacheManager>(
initialContext.cacheManager
);
const [cache, setCache] = useState<DetailedInfinispanCache>(
initialContext.cache
);
Expand Down Expand Up @@ -52,19 +56,28 @@ const CacheDetailProvider = ({ children }) => {

const fetchCache = () => {
if (loading) {
ConsoleServices.caches()
.retrieveFullDetail(cacheName)
.then((eitherDetail) => {
if (eitherDetail.isRight()) {
setCache(eitherDetail.value);
} else {
setError(eitherDetail.value.message);
}
})
.finally(() => {
setLoading(false);
setLoadingEntries(true);
});
ConsoleServices.dataContainer().getDefaultCacheManager()
.then(maybeCm => {
if (maybeCm.isRight()) {
setCacheManager(maybeCm.value);
ConsoleServices.caches()
.retrieveFullDetail(cacheName)
.then((eitherDetail) => {
if (eitherDetail.isRight()) {
setCache(eitherDetail.value);
} else {
setError(eitherDetail.value.message);
}
})
.finally(() => {
setLoading(false);
setLoadingEntries(true);
});
} else {
setError(maybeCm.value.message);
}
})

}
};

Expand Down Expand Up @@ -117,6 +130,7 @@ const CacheDetailProvider = ({ children }) => {
loadCache: useCallback(loadCache, []),
reload: useCallback(() => setLoading(true), []),
cache: cache,
cacheManager: cacheManager,
cacheEntries: cacheEntries,
loadingEntries: loadingEntries,
errorEntries: errorEntries,
Expand Down
6 changes: 6 additions & 0 deletions src/app/providers/CacheManagerContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const initialContext = {
caches: [] as CacheInfo[],
loadingCaches: true,
errorCaches: '',
reload: () => {},
reloadCaches: () => {},
};

Expand Down Expand Up @@ -76,6 +77,10 @@ const ContainerDataProvider = ({ children }) => {
}
}, [cm, loadingCaches]);

const reload = () => {
setLoading(true);
};

const reloadCaches = () => {
setLoadingCaches(true);
};
Expand All @@ -87,6 +92,7 @@ const ContainerDataProvider = ({ children }) => {
cm: cm,
loadingCaches: loadingCaches,
errorCaches: errorCaches,
reload: useCallback(reload, []),
reloadCaches: useCallback(reloadCaches, []),
};

Expand Down
4 changes: 2 additions & 2 deletions src/app/services/cachesHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ export function useCacheEntries() {
}

export function useCacheDetail() {
const { cache, loading, error, loadCache, reload } = useContext(
const { cache, loading, error, loadCache, reload, cacheManager } = useContext(
CacheDetailContext
);

return { cache, loading, error, loadCache, reload };
return { cache, loading, error, loadCache, reload, cacheManager };
}
3 changes: 2 additions & 1 deletion src/app/services/dataContainerHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { useContext } from 'react';
import { DataContainerContext } from '@app/providers/CacheManagerContextProvider';

export function useDataContainer() {
const { cm, loading, error } = useContext(DataContainerContext);
const { cm, loading, error, reload } = useContext(DataContainerContext);
return {
loading,
error,
cm,
reload
};
}

Expand Down
9 changes: 4 additions & 5 deletions src/services/cacheConfigUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ContentType, EncodingType } from '@services/infinispanRefData';
import {Either, left, right} from "@services/either";
import { Either, left, right } from '@services/either';

export const Distributed = 'distributed-cache';
export const Replicated = 'replicated-cache';
Expand All @@ -11,18 +11,17 @@ 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'> {
public static validateConfig(config: string): Either<string, 'xml' | 'json'> {
const trimmedConf = config.trim();

if (trimmedConf.length == 0) {
return left('Configuration can\'t be empty');
return left("Configuration can't be empty");
}
try {
JSON.parse(trimmedConf);
Expand All @@ -36,7 +35,7 @@ export class CacheConfigUtils {
}
} catch (ex) {}
return left('The provided configuration is not a valid XML or JSON.');
};
}

/**
* Map the encoding type of the cache
Expand Down

0 comments on commit 7716e6c

Please sign in to comment.