From: Herbert Eiselt Date: Fri, 7 Jun 2019 15:40:50 +0000 (+0200) Subject: SDNR Add missing status bar to ODLUX Framework X-Git-Tag: 0.5.0~16 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=d93e6a996e60fb6abce9a870cef6b2d57bfa70fd;p=ccsdk%2Ffeatures.git SDNR Add missing status bar to ODLUX Framework Modify framework and adapt all apps Issue-ID: SDNC-789 Signed-off-by: Herbert Eiselt Change-Id: I1ea0a3df6c3f6db08f2bd7a21eb3b4cbf230a08a Signed-off-by: Herbert Eiselt --- diff --git a/sdnr/wt/odlux/apps/configurationApp/src/actions/configurationActions.ts b/sdnr/wt/odlux/apps/configurationApp/src/actions/configurationActions.ts index 82055a761..b0ffc4c19 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/actions/configurationActions.ts +++ b/sdnr/wt/odlux/apps/configurationApp/src/actions/configurationActions.ts @@ -96,7 +96,7 @@ export const updateLpIdAsyncActionCreator = (lpId: string | undefined) => async export const updateViewDataAsyncActionCreator = (viewId: string | undefined, indexValues: string[] = []) => async (dispatch: Dispatch, getState: () => IApplicationStoreState) => { const { configuration: { nodeId, lpId, capability, conditionalPackage, viewSpecifications } } = getState(); if (!viewId || !capability || !nodeId || !lpId || !conditionalPackage) { - dispatch(new AddSnackbarNotification({ message: `Error invalid parameter !${JSON.stringify({viewId ,capability ,nodeId ,lpId ,conditionalPackage}, null,2)}`, options: { variant: 'error' } })); + // dispatch(new AddSnackbarNotification({ message: `Error invalid parameter !${JSON.stringify({capability ,nodeId ,lpId ,conditionalPackage}, null,2)}`, options: { variant: 'error' } })); dispatch(new UpdateViewData()); return; } @@ -131,7 +131,7 @@ export const updateViewDataAsyncActionCreator = (viewId: string | undefined, ind viewData = viewData[path]; } - return viewData ? + return viewData != null ? dispatch(new UpdateViewData(viewId, indexValues.length > 0 ? indexValues.join("/") : "", viewData)) : dispatch(new UpdateViewData()); } \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/configurationApp/src/handlers/configurationAppRootHandler.ts b/sdnr/wt/odlux/apps/configurationApp/src/handlers/configurationAppRootHandler.ts index 4b982149a..f82d08a1b 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/handlers/configurationAppRootHandler.ts +++ b/sdnr/wt/odlux/apps/configurationApp/src/handlers/configurationAppRootHandler.ts @@ -44,7 +44,14 @@ export const configurationAppRootHandler: IActionHandler { const capFile = capability && revision && `${capability}@${revision}.json`; - const coreModelResponse = capFile && await requestRest<{ views: ViewSpecification[] } >(`assets/${capFile}`, { method: "GET" }); - return coreModelResponse && coreModelResponse.views || null; + const coreModelResponse = capFile && await requestRest<{ views: ViewSpecification[] }>(`assets/${capFile}`, { method: "GET" }, false, true); + return coreModelResponse && coreModelResponse.views || null; } } diff --git a/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx b/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx index 5865c10e5..65fbd70a5 100644 --- a/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx +++ b/sdnr/wt/odlux/apps/configurationApp/src/views/configurationApplication.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { MaterialTable, ColumnType, MaterialTableCtorType } from '../../../../framework/src/components/material-table'; +import { MaterialTable, MaterialTableCtorType } from '../../../../framework/src/components/material-table'; import connect, { Connect, IDispatcher } from '../../../../framework/src/flux/connect'; import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; import { IConnectAppStoreState } from '../../../connectApp/src/handlers/connectAppRootHandler'; @@ -70,11 +70,12 @@ class ConfigurationApplicationComponent extends React.Component ); } else if (!this.props.lpId) { - return ( + return this.props.coreModel && this.props.coreModel.ltp && this.props.coreModel.ltp.length + ? ( <>

Please select an existing LP first !

    - { this.props.coreModel && this.props.coreModel.ltp.map(ltp => { + { this.props.coreModel.ltp.map(ltp => { return
  • { this.props.changeLp(ltp.lp[0].uuid); @@ -83,6 +84,11 @@ class ConfigurationApplicationComponent extends React.Component + ) + : ( + <> +

    No LTP / LP found !

    + ); } else if (!this.props.capability && !this.props.viewId) { return ( @@ -113,7 +119,7 @@ class ConfigurationApplicationComponent extends React.Component ) - :

    View Not Found

    ; + :

    View [{this.props.viewId || this.props.conditionalPackage}] Not Found ! {this.props.viewSpecifications.length}

    ; } private static keyPropertyParser = /\$\$INDEX:(\d+):?([a-z\-]+)?\$\$$/; diff --git a/sdnr/wt/odlux/apps/faultApp/src/actions/statusActions.ts b/sdnr/wt/odlux/apps/faultApp/src/actions/statusActions.ts new file mode 100644 index 000000000..48f501ba8 --- /dev/null +++ b/sdnr/wt/odlux/apps/faultApp/src/actions/statusActions.ts @@ -0,0 +1,26 @@ +import { FaultApplicationBaseAction } from './notificationActions'; +import { getFaultStateFromDatabase } from '../services/faultStatusService'; +import { Dispatch } from '../../../../framework/src/flux/store'; + + +export class SetFaultStatusAction extends FaultApplicationBaseAction { + constructor (public criticalFaults: number, public majorFaults: number, public minorFaults: number, public warnings: number) { + super(); + } +} + + +export const refreshFaultStatusAsyncAction = async (dispatch: Dispatch ) => { + const result = await getFaultStateFromDatabase().catch(_=>null); + if (result) { + const statusAction = new SetFaultStatusAction( + result["Critical"] || 0, + result["Major"] || 0, + result["Minor"] || 0, + result["Warning"] || 0 + ); + dispatch(statusAction); + return; + } + dispatch(new SetFaultStatusAction(0, 0, 0, 0)); +} diff --git a/sdnr/wt/odlux/apps/faultApp/src/components/faultStatus.tsx b/sdnr/wt/odlux/apps/faultApp/src/components/faultStatus.tsx new file mode 100644 index 000000000..e83720f0b --- /dev/null +++ b/sdnr/wt/odlux/apps/faultApp/src/components/faultStatus.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; + +import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles'; +import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; // select app icon + +import connect, { Connect } from '../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; + +import Typography from '@material-ui/core/Typography'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +const styles = (theme: Theme) => createStyles({ + icon: { + marginLeft: 8, + marginRight: 8 + }, + critical: { + color: "red" + }, + major: { + color: "orange" + }, + minor: { + color: "#f7f700" + }, + warning: { + color: "#428bca" + } +}); + +const mapProps = (state: IApplicationStoreState) => ({ + faultStatus: state.fault.faultStatus, +}); + + +type FaultStatusComponentProps = & WithStyles & Connect; + +class FaultStatusComponent extends React.Component { + render(): JSX.Element { + const { classes, faultStatus } = this.props; + + return ( + + Alarm status: { faultStatus.critical } | + { faultStatus.major } | + { faultStatus.minor } | + { faultStatus.warning } | + + ); + }; +} + +export const FaultStatus = withStyles(styles)(connect(mapProps)(FaultStatusComponent)); +export default FaultStatus; \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts b/sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts index a887a3327..e97383e10 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts +++ b/sdnr/wt/odlux/apps/faultApp/src/handlers/faultAppRootHandler.ts @@ -10,12 +10,14 @@ import { IFaultNotifications, faultNotificationsHandler } from './notificationsH import { ICurrentProblemsState, currentProblemsActionHandler } from './currentProblemsHandler'; import { IAlarmLogEntriesState, alarmLogEntriesActionHandler } from './alarmLogEntriesHandler'; import { SetPanelAction } from '../actions/panelChangeActions'; +import { IFaultStatus, faultStatusHandler } from './faultStatusHandler'; export interface IFaultAppStoreState { currentProblems: ICurrentProblemsState; faultNotifications: IFaultNotifications; alarmLogEntries: IAlarmLogEntriesState; currentOpenPanel: string|null; + faultStatus: IFaultStatus; } const currentOpenPanelHandler: IActionHandler = (state = null, action) => { @@ -35,7 +37,8 @@ const actionHandlers = { currentProblems: currentProblemsActionHandler, faultNotifications: faultNotificationsHandler, alarmLogEntries: alarmLogEntriesActionHandler, - currentOpenPanel: currentOpenPanelHandler + currentOpenPanel: currentOpenPanelHandler, + faultStatus: faultStatusHandler }; export const faultAppRootHandler = combineActionHandler(actionHandlers); diff --git a/sdnr/wt/odlux/apps/faultApp/src/handlers/faultStatusHandler.ts b/sdnr/wt/odlux/apps/faultApp/src/handlers/faultStatusHandler.ts new file mode 100644 index 000000000..0a084df6b --- /dev/null +++ b/sdnr/wt/odlux/apps/faultApp/src/handlers/faultStatusHandler.ts @@ -0,0 +1,29 @@ +import { IActionHandler } from "../../../../framework/src/flux/action"; +import { SetFaultStatusAction } from "../actions/statusActions"; + +export interface IFaultStatus { + critical: number, + major: number, + minor: number, + warning: number +} + +const faultStatusInit: IFaultStatus = { + critical: 0, + major: 0, + minor: 0, + warning: 0 +}; + +export const faultStatusHandler: IActionHandler = (state = faultStatusInit, action) => { + if (action instanceof SetFaultStatusAction) { + state = { + critical: action.criticalFaults, + major: action.majorFaults, + minor: action.minorFaults, + warning: action.warnings + } + } + + return state; +} \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/faultApp/src/index.html b/sdnr/wt/odlux/apps/faultApp/src/index.html index 5f6794f33..a2a0830b3 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/index.html +++ b/sdnr/wt/odlux/apps/faultApp/src/index.html @@ -15,10 +15,14 @@ diff --git a/sdnr/wt/odlux/apps/faultApp/src/plugin.tsx b/sdnr/wt/odlux/apps/faultApp/src/plugin.tsx index c4545ad1a..be1e075fc 100644 --- a/sdnr/wt/odlux/apps/faultApp/src/plugin.tsx +++ b/sdnr/wt/odlux/apps/faultApp/src/plugin.tsx @@ -20,7 +20,9 @@ import { PanelId } from "./models/panelId"; import { SetPanelAction } from "./actions/panelChangeActions"; import { AddFaultNotificationAction } from "./actions/notificationActions"; -import { createCurrentProblemsProperties, createCurrentProblemsActions } from "./handlers/currentProblemsHandler"; +import { createCurrentProblemsProperties, createCurrentProblemsActions, currentProblemsReloadAction } from "./handlers/currentProblemsHandler"; +import { FaultStatus } from "./components/faultStatus"; +import { refreshFaultStatusAsyncAction } from "./actions/statusActions"; let currentMountId: string | undefined = undefined; @@ -65,6 +67,7 @@ export function register() { icon: faBell, rootComponent: App, rootActionHandler: faultAppRootHandler, + statusBarElement: FaultStatus, menuEntry: "Fault" }); @@ -75,4 +78,18 @@ export function register() { store.dispatch(new AddFaultNotificationAction(fault)); } })); + + applicationApi.applicationStoreInitialized.then(store => { + store.dispatch(currentProblemsReloadAction); + }); + + applicationApi.applicationStoreInitialized.then(store => { + store.dispatch(refreshFaultStatusAsyncAction); + }); + window.setInterval(() => { + applicationApi.applicationStoreInitialized.then(store => { + store.dispatch(refreshFaultStatusAsyncAction); + }); + }, 15000); + } diff --git a/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts b/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts new file mode 100644 index 000000000..ad0d394ce --- /dev/null +++ b/sdnr/wt/odlux/apps/faultApp/src/services/faultStatusService.ts @@ -0,0 +1,22 @@ +import { requestRest } from "../../../../framework/src/services/restService"; +import { Result } from "../../../../framework/src/models/elasticSearch"; + +export const getFaultStateFromDatabase = async (): Promise < { [key: string]: number } | null > => { + const path = 'database/sdnevents/faultcurrent/_search'; + const query = { + "size": 0, + "aggregations": { + "severity": { + "terms": { + "field": "faultCurrent.severity" + } + } + } + }; + + const result = await requestRest>(path, { method: "POST", body: JSON.stringify(query) }); + return result && result.aggregations && result.aggregations["severity"].buckets.reduce<{ [key: string]: number }>((acc, cur) => { + acc[cur.key] = cur.doc_count; + return acc; + }, {}) || null; +} \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/faultApp/webpack.config.js b/sdnr/wt/odlux/apps/faultApp/webpack.config.js index a0284c5dd..bbf33ea2f 100644 --- a/sdnr/wt/odlux/apps/faultApp/webpack.config.js +++ b/sdnr/wt/odlux/apps/faultApp/webpack.config.js @@ -124,8 +124,26 @@ module.exports = (env) => { colors: true }, proxy: { - "/database": { - target: "http://localhost:8181", + "/oauth2/": { + target: "http://localhost:3000", + secure: false + }, + "/database/": { + target: "http://localhost:3000", + secure: false + }, + "/restconf/": { + target: "http://localhost:3000", + secure: false + }, + "/help/": { + target: "http://localhost:3000", + secure: false + }, + "/websocket/": { + target: "http://localhost:3000", + ws: true, + changeOrigin: true, secure: false } } diff --git a/sdnr/wt/odlux/apps/helpApp/src/components/helpStatus.tsx b/sdnr/wt/odlux/apps/helpApp/src/components/helpStatus.tsx new file mode 100644 index 000000000..813fffd19 --- /dev/null +++ b/sdnr/wt/odlux/apps/helpApp/src/components/helpStatus.tsx @@ -0,0 +1,63 @@ +import * as React from 'react'; + +import { withStyles, WithStyles, createStyles, Theme } from '@material-ui/core/styles'; +import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'; // select app icon + +import connect, { Connect } from '../../../../framework/src/flux/connect'; +import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore'; + +import Typography from '@material-ui/core/Typography'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faQuestionCircle } from '@fortawesome/free-solid-svg-icons'; +import { withRouter, RouteComponentProps } from 'react-router'; + +const styles = (theme: Theme) => createStyles({ + icon: { + marginLeft: 8, + marginRight: 8 + }, + disabled: { + color: theme.palette.grey[400] + }, + link: { + cursor: "pointer", + '&:hover': { + textDecoration: "underline" + } + } +}); + +const mapProps = (state: IApplicationStoreState) => ({ + appId: state.framework.applicationState.appId, + toc: state.help.toc +}); + + +type HelpStatusComponentProps = & RouteComponentProps & WithStyles & Connect; + +class HelpStatusComponent extends React.Component { + render() { + const { classes, history, toc, appId } = this.props; + const rootNode = toc && toc.find(t => t.id === "sdnr"); + const helpNode = appId + ? rootNode && rootNode.nodes && rootNode.nodes.find(n => n.id === appId || n.id === appId+"App") + : rootNode; + return helpNode + ? ( + { event.stopPropagation(); history.push(`/help/${helpNode.uri}`) }} > + + Help + + ) + : ( + + + Help + + ); + }; + +} + +export const HelpStatus = withRouter(withStyles(styles)(connect(mapProps)(HelpStatusComponent))); +export default HelpStatus; \ No newline at end of file diff --git a/sdnr/wt/odlux/apps/helpApp/src/index.html b/sdnr/wt/odlux/apps/helpApp/src/index.html index 6865db051..e76109fd8 100644 --- a/sdnr/wt/odlux/apps/helpApp/src/index.html +++ b/sdnr/wt/odlux/apps/helpApp/src/index.html @@ -14,11 +14,15 @@ diff --git a/sdnr/wt/odlux/apps/helpApp/src/models/tocNode.ts b/sdnr/wt/odlux/apps/helpApp/src/models/tocNode.ts index ae73ec43d..ddb5e729e 100644 --- a/sdnr/wt/odlux/apps/helpApp/src/models/tocNode.ts +++ b/sdnr/wt/odlux/apps/helpApp/src/models/tocNode.ts @@ -5,7 +5,7 @@ export type VersionInfo = { } export type TocNode = { - label: string; + label: string; versions: { [versionKey: string]: VersionInfo, current: VersionInfo @@ -17,6 +17,7 @@ export type TocNodeCollection = { [tocNodeKey: string]: TocNode }; export type TocTreeNode = { + id: string; label: string; uri: string; nodes?: TocTreeNode[]; diff --git a/sdnr/wt/odlux/apps/helpApp/src/plugin.tsx b/sdnr/wt/odlux/apps/helpApp/src/plugin.tsx index f871ab9d9..94f65b870 100644 --- a/sdnr/wt/odlux/apps/helpApp/src/plugin.tsx +++ b/sdnr/wt/odlux/apps/helpApp/src/plugin.tsx @@ -14,6 +14,7 @@ import { helpAppRootHandler } from './handlers/helpAppRootHandler'; import { HelpApplication } from './views/helpApplication'; import { SubMenuEntry } from "./components/subMenuEntry"; +import { HelpStatus } from "./components/helpStatus"; import '!style-loader!css-loader!highlight.js/styles/default.css'; @@ -58,6 +59,7 @@ export async function register() { icon: faFirstAid, rootComponent: App, rootActionHandler: helpAppRootHandler, + statusBarElement: HelpStatus, menuEntry: "Help", subMenuEntry: SubMenuEntry }); diff --git a/sdnr/wt/odlux/apps/helpApp/src/services/helpService.ts b/sdnr/wt/odlux/apps/helpApp/src/services/helpService.ts index 800e0b47f..aa0b0ed43 100644 --- a/sdnr/wt/odlux/apps/helpApp/src/services/helpService.ts +++ b/sdnr/wt/odlux/apps/helpApp/src/services/helpService.ts @@ -29,6 +29,7 @@ class HelpService { return Object.keys(col).reduce ((acc, key) => { const current = col[key]; acc.push({ + id: key, label: current.label, uri: current.versions.current.path, nodes: current.nodes && mapNodesCollection(current.nodes) || undefined diff --git a/sdnr/wt/odlux/apps/helpApp/webpack.config.js b/sdnr/wt/odlux/apps/helpApp/webpack.config.js index f9448a310..3a56d8bea 100644 --- a/sdnr/wt/odlux/apps/helpApp/webpack.config.js +++ b/sdnr/wt/odlux/apps/helpApp/webpack.config.js @@ -123,7 +123,6 @@ module.exports = (env) => { }]), ] ], - devServer: { public: "http://localhost:3100", contentBase: frameworkPath, diff --git a/sdnr/wt/odlux/core/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/model/bundles/OdluxBundleLoader.java b/sdnr/wt/odlux/core/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/model/bundles/OdluxBundleLoader.java index 5c8231e9c..ce003c664 100644 --- a/sdnr/wt/odlux/core/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/model/bundles/OdluxBundleLoader.java +++ b/sdnr/wt/odlux/core/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/model/bundles/OdluxBundleLoader.java @@ -25,4 +25,6 @@ public interface OdluxBundleLoader { public int getNumberOfBundles(); + public String getResourceContent(String fn, OdluxBundleResourceAccess indexBundle); + } diff --git a/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/IndexOdluxBundle.java b/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/IndexOdluxBundle.java index dfd450f67..d335e52c7 100644 --- a/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/IndexOdluxBundle.java +++ b/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/IndexOdluxBundle.java @@ -98,7 +98,7 @@ public class IndexOdluxBundle extends OdluxBundle implements OdluxBundleResource } in.close(); } catch (IOException e) { - LOG.warn("could not load resfile " + url.toString() + ": " + e.getMessage()); + LOG.warn("could not load resfile {} : {}", url, e.getMessage()); return null; } diff --git a/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/OdluxBundleLoaderImpl.java b/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/OdluxBundleLoaderImpl.java index be271026d..205c96129 100644 --- a/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/OdluxBundleLoaderImpl.java +++ b/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/OdluxBundleLoaderImpl.java @@ -84,11 +84,6 @@ public class OdluxBundleLoaderImpl implements OdluxBundleLoader { } - private Comparator getBundleSorter() { - return this.sortorderbundlecomparator; - } - - public List getLoadedBundles(String myBundleName) { List list = new ArrayList<>(); for (OdluxBundle b : bundles2) { @@ -107,7 +102,7 @@ public class OdluxBundleLoaderImpl implements OdluxBundleLoader { return names; } - public String getResource(String fn, OdluxBundleResourceAccess indexBundle) { + public String getResourceContent(String fn, OdluxBundleResourceAccess indexBundle) { String fileContent = null; if (indexBundle.hasResource(fn)) { diff --git a/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/ResFilesServlet.java b/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/ResFilesServlet.java index 41d10adfa..fe00662aa 100644 --- a/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/ResFilesServlet.java +++ b/sdnr/wt/odlux/core/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/odlux/ResFilesServlet.java @@ -19,21 +19,23 @@ package org.onap.ccsdk.features.sdnr.wt.odlux; import java.io.IOException; import java.io.OutputStream; +import java.net.HttpURLConnection; + import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.onap.ccsdk.features.sdnr.wt.odlux.IndexOdluxBundle; + +import org.onap.ccsdk.features.sdnr.wt.odlux.model.bundles.OdluxBundleLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ResFilesServlet extends HttpServlet { - /** - * - */ private static final long serialVersionUID = -6807215213921798293L; private static Logger LOG = LoggerFactory.getLogger(ResFilesServlet.class); + + private final IndexOdluxBundle indexBundle; public ResFilesServlet() { @@ -41,32 +43,46 @@ public class ResFilesServlet extends HttpServlet { indexBundle = new IndexOdluxBundle(); } - @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - LOG.debug("get req: " + req.getRequestURI().toString()); - final String fn = req.getRequestURI().toString(); - String fileContent = null; - - fileContent = OdluxBundleLoaderImpl.getInstance().getResource(fn, indexBundle); + final String fn = req.getRequestURI(); + LOG.debug("Get request with for URI: {}", fn); - if (fileContent != null) { - LOG.debug("found " + fn + " in res. write to output stream"); - resp.setStatus(200); - OutputStream os = resp.getOutputStream(); - os.write(fileContent.getBytes(java.nio.charset.StandardCharsets.UTF_8)); - os.flush(); - os.close(); - } else { - LOG.debug("file " + fn + " not found in res."); - resp.setStatus(404); + OdluxBundleLoader odluxBundleLoader = OdluxBundleLoaderImpl.getInstance(); + if (odluxBundleLoader != null) { + String fileContent = odluxBundleLoader.getResourceContent(fn, indexBundle); + if (fileContent != null) { + //Store header info + String mimeType = getMimeType(fn); + byte[] byteContent = fileContent.getBytes(java.nio.charset.StandardCharsets.UTF_8); + int length = byteContent.length; - } + LOG.debug("Found file in resources. Name {} mimetype {} length {} and write to output stream", fn, mimeType, length); + resp.setContentType(mimeType); + resp.setContentLength(length); + resp.setStatus(HttpURLConnection.HTTP_OK); + OutputStream os = resp.getOutputStream(); + os.write(byteContent); + os.flush(); + os.close(); + } else { + LOG.debug("File {} not found in res.", fn); + resp.setStatus(HttpURLConnection.HTTP_NOT_FOUND); + } + } else { + LOG.debug("BundleLoaderInstance to found.", fn); + resp.setStatus(HttpURLConnection.HTTP_NOT_FOUND); + } } public String loadFileContent(String filename) { return this.indexBundle.getResourceFileContent(filename); } + //Provide own function that can be overloaded for test + public String getMimeType(String fileName) { + return getServletContext().getMimeType(fileName); + } + } diff --git a/sdnr/wt/odlux/core/provider/src/test/java/org/onap/ccsdk/features/sdnr/odlux/test/TestResFileServlet.java b/sdnr/wt/odlux/core/provider/src/test/java/org/onap/ccsdk/features/sdnr/odlux/test/TestResFileServlet.java index 287ed70d9..217735c40 100644 --- a/sdnr/wt/odlux/core/provider/src/test/java/org/onap/ccsdk/features/sdnr/odlux/test/TestResFileServlet.java +++ b/sdnr/wt/odlux/core/provider/src/test/java/org/onap/ccsdk/features/sdnr/odlux/test/TestResFileServlet.java @@ -21,7 +21,9 @@ import static org.junit.Assert.*; import java.io.IOException; import java.io.StringWriter; +import java.net.HttpURLConnection; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; @@ -38,6 +40,24 @@ public class TestResFileServlet { PublicResFilesServlet servlet; + @Test + public void test() throws ServletException { + servlet = new PublicResFilesServlet(); + servlet.init(); + + OdluxBundleLoader loader = OdluxBundleLoaderImpl.getInstance(); + OdluxBundle b = new OdluxBundle(); + b.setBundleName("b1"); + b.setIndex(9); + b.setLoader(loader); + b.initialize(); + System.out.println("Subtest1"); + testResReq("odlux/index.html", HttpURLConnection.HTTP_OK); + System.out.println("Subtest2"); + testResReq("odlux/fragmich.txt", HttpURLConnection.HTTP_NOT_FOUND); + System.out.println("Done"); + } + private void testResReq(String res, int responseCode) { HttpServletRequest req = mock(HttpServletRequest.class); HttpServletResponse resp = mock(HttpServletResponse.class); @@ -69,19 +89,6 @@ public class TestResFileServlet { verify(resp).setStatus(responseCode); } - @Test - public void test() { - servlet = new PublicResFilesServlet(); - OdluxBundleLoader loader = OdluxBundleLoaderImpl.getInstance(); - OdluxBundle b = new OdluxBundle(); - b.setBundleName("b1"); - b.setIndex(9); - b.setLoader(loader); - b.initialize(); - testResReq("odlux/index.html", 200); - testResReq("odlux/fragmich.txt", 404); - - } @SuppressWarnings("serial") private class PublicResFilesServlet extends ResFilesServlet { @@ -89,5 +96,9 @@ public class TestResFileServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } + @Override + public String getMimeType(String fileName) { + return "mimetype"; + } } } diff --git a/sdnr/wt/odlux/core/provider/src/test/resources/log4j.properties b/sdnr/wt/odlux/core/provider/src/test/resources/log4j.properties deleted file mode 100644 index 142663bd2..000000000 --- a/sdnr/wt/odlux/core/provider/src/test/resources/log4j.properties +++ /dev/null @@ -1,12 +0,0 @@ -log4j.rootLogger=INFO, out - -log4j.logger.org.apache.camel.impl.converter=WARN -log4j.logger.org.apache.camel.management=WARN -log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN -log4j.logger.org.springframework=ERROR - -# CONSOLE appender not used by default -log4j.appender.out=org.apache.log4j.ConsoleAppender -log4j.appender.out.layout=org.apache.log4j.PatternLayout -log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n - diff --git a/sdnr/wt/odlux/core/provider/src/test/resources/simplelogger.properties b/sdnr/wt/odlux/core/provider/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..426f84834 --- /dev/null +++ b/sdnr/wt/odlux/core/provider/src/test/resources/simplelogger.properties @@ -0,0 +1,38 @@ +# SLF4J's SimpleLogger configuration file +# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err. + +# Default logging detail level for all instances of SimpleLogger. +# Must be one of ("trace", "debug", "info", "warn", or "error"). +# If not specified, defaults to "info". +org.slf4j.simpleLogger.defaultLogLevel=debug + +# Logging detail level for a SimpleLogger instance named "xxx.yyy.zzz". +# Must be one of ("trace", "debug", "info", "warn", or "error"). +# If not specified, the default logging detail level is used. +# org.slf4j.simpleLogger.log.xxx.yyy=debug +org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager=info +org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager.archiveservice=debug +org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager.base.internalTypes.Resources=info +org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.container=info + +# Set to true if you want the current date and time to be included in output messages. +# Default is false, and will output the number of milliseconds elapsed since startup. +#org.slf4j.simpleLogger.showDateTime=false + +# The date and time format to be used in the output messages. +# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat. +# If the format is not specified or is invalid, the default format is used. +# The default format is yyyy-MM-dd HH:mm:ss:SSS Z. +#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z + +# Set to true if you want to output the current thread name. +# Defaults to true. +#org.slf4j.simpleLogger.showThreadName=true + +# Set to true if you want the Logger instance name to be included in output messages. +# Defaults to true. +#org.slf4j.simpleLogger.showLogName=true + +# Set to true if you want the last component of the name to be included in output messages. +# Defaults to false. +#org.slf4j.simpleLogger.showShortLogName=false diff --git a/sdnr/wt/odlux/framework/pom.xml b/sdnr/wt/odlux/framework/pom.xml index 2b648e273..1ffdd397c 100644 --- a/sdnr/wt/odlux/framework/pom.xml +++ b/sdnr/wt/odlux/framework/pom.xml @@ -16,7 +16,7 @@ ${maven.build.timestamp} ONAP Dublin (Flourine-SR2) - 8.c7848df(19/04/03) + 9.ac4a3af(19/06/06) ONAP SDN-R | ONF Wireless for ${distversion} - Build: ${buildtime} ${buildno} ${project.version} diff --git a/sdnr/wt/odlux/framework/src/actions/titleActions.ts b/sdnr/wt/odlux/framework/src/actions/titleActions.ts index b641bab95..4e5174d59 100644 --- a/sdnr/wt/odlux/framework/src/actions/titleActions.ts +++ b/sdnr/wt/odlux/framework/src/actions/titleActions.ts @@ -1,10 +1,10 @@ import { Action } from '../flux/action'; -import { IconType } from '../models/iconDefinition'; +import { IconType } from '../models/iconDefinition'; export class SetTitleAction extends Action { - - constructor(public title: string, public icon?: IconType) { + + constructor(public title: string, public icon?: IconType, public appId?: string) { super(); } } \ No newline at end of file diff --git a/sdnr/wt/odlux/framework/src/components/routing/appFrame.tsx b/sdnr/wt/odlux/framework/src/components/routing/appFrame.tsx index 55b249246..06ad5b434 100644 --- a/sdnr/wt/odlux/framework/src/components/routing/appFrame.tsx +++ b/sdnr/wt/odlux/framework/src/components/routing/appFrame.tsx @@ -5,29 +5,30 @@ import connect, { Connect } from '../../flux/connect'; import { SetTitleAction } from '../../actions/titleActions'; import { AddErrorInfoAction } from '../../actions/errorActions'; -import { IconType } from '../../models/iconDefinition'; +import { IconType } from '../../models/iconDefinition'; export interface IAppFrameProps { title: string; icon?: IconType; + appId?: string } -/** - * Represents a component to wich will embed each single app providing the +/** + * Represents a component to wich will embed each single app providing the * functionality to update the title and implement an exeprion border. */ export class AppFrame extends React.Component { - + public render(): JSX.Element { return ( -
    +
    { this.props.children }
    ) } - + public componentDidMount() { - this.props.dispatch(new SetTitleAction(this.props.title, this.props.icon)); + this.props.dispatch(new SetTitleAction(this.props.title, this.props.icon, this.props.appId)); } public componentDidCatch(error: Error | null, info: object) { this.props.dispatch(new AddErrorInfoAction({ error, info })); diff --git a/sdnr/wt/odlux/framework/src/components/titleBar.tsx b/sdnr/wt/odlux/framework/src/components/titleBar.tsx index a3ba571ec..230dda400 100644 --- a/sdnr/wt/odlux/framework/src/components/titleBar.tsx +++ b/sdnr/wt/odlux/framework/src/components/titleBar.tsx @@ -69,12 +69,18 @@ class TitleBarComponent extends React.Component - + { state.framework.applicationState.icon ? () : null } { state.framework.applicationState.title } +
    + { state.framework.applicationRegistraion && Object.keys(state.framework.applicationRegistraion).map(key => { + const reg = state.framework.applicationRegistraion[key]; + return reg && reg.statusBarElement && || null + })} + { state.framework.authenticationState.user ? (