diff options
author | Yarin Dekel <yarind@amdocs.com> | 2018-12-26 13:14:01 +0200 |
---|---|---|
committer | Yarin Dekel <yarind@amdocs.com> | 2018-12-26 13:14:05 +0200 |
commit | bd2841ad36ef57983f8669b470e661d46d309012 (patch) | |
tree | 01ef36edbdab7c80298db0382b4ca635127cfd8b | |
parent | 11ed075eb955be52b1326692fe401dd8e743f4c2 (diff) |
WF-validation to empty artifact
Issue-ID: SDC-2023
Change-Id: Idcc690cfad19da0d29232c93b202042f6230ffaf
Signed-off-by: Yarin Dekel <yarind@amdocs.com>
11 files changed, 106 insertions, 39 deletions
diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java index 0078d226..33210778 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java @@ -232,9 +232,10 @@ public class WorkflowVersionManagerImpl implements WorkflowVersionManager { workflowId, versionId); throw new VersionModificationException(workflowId, versionId); } - - artifactRepository.delete(workflowId, versionId); - versioningManager.publish(workflowId, new Version(versionId), "Delete Artifact"); + if(retrievedVersion.isHasArtifact()) { + artifactRepository.delete(workflowId, versionId); + versioningManager.publish(workflowId, new Version(versionId), "Delete Artifact"); + } } private void validateVersionExistAndCertified(String workflowId, List<Version> versions, String versionId) { diff --git a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java index 640d3e8b..8e714f62 100644 --- a/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java +++ b/workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java @@ -399,15 +399,28 @@ public class WorkflowVersionManagerImplTest { } @Test - public void shouldDeleteArtifact() { + public void shouldNotDeleteArtifactIfNotExist() { doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); Version version = new Version(VERSION1_ID); doReturn(version).when(versioningManagerMock).get(ITEM1_ID, version); WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); doReturn(workflowVersion).when(versionMapperMock).versionToWorkflowVersion(version); workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); - verify(artifactRepositoryMock).delete(ITEM1_ID, VERSION1_ID); - verify(versioningManagerMock).publish(ITEM1_ID, version, "Delete Artifact"); + verify(artifactRepositoryMock, times(0)).delete(ITEM1_ID, VERSION1_ID); + verify(versioningManagerMock, times(0)).publish(ITEM1_ID, version, "Delete Artifact"); + } + + @Test + public void shouldDeleteArtifactIfExist() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + Version version = new Version(VERSION1_ID); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, version); + WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); + doReturn(true).when(artifactRepositoryMock).isExist(ITEM1_ID, VERSION1_ID); + doReturn(workflowVersion).when(versionMapperMock).versionToWorkflowVersion(version); + workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); + verify(artifactRepositoryMock, times(1)).delete(ITEM1_ID, VERSION1_ID); + verify(versioningManagerMock, times(1)).publish(ITEM1_ID, version, "Delete Artifact"); } private static Version eqVersion(String versionId) { diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js index 529627d5..e444d98c 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js +++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/CompositionView.js @@ -16,15 +16,16 @@ import React, { Component } from 'react'; import fileSaver from 'file-saver'; import isEqual from 'lodash.isequal'; -import CustomModeler from './custom-modeler'; +import PropTypes from 'prop-types'; import propertiesPanelModule from 'bpmn-js-properties-panel'; +import { I18n } from 'react-redux-i18n'; + +import CustomModeler from './custom-modeler'; import propertiesProviderModule from './custom-properties-provider/provider/camunda'; import camundaModuleDescriptor from './custom-properties-provider/descriptors/camunda'; import newDiagramXML from './newDiagram.bpmn'; -import PropTypes from 'prop-types'; import CompositionButtons from './components/CompositionButtonsPanel'; import { setElementInputsOutputs } from './bpmnUtils.js'; -import { I18n } from 'react-redux-i18n'; import { PROCESS_DEFAULT_ID, COMPOSITION_ERROR_COLOR, @@ -79,10 +80,6 @@ class CompositionView extends Component { this.generatedId = 'bpmn-container' + Date.now(); this.fileInput = React.createRef(); this.bpmnContainer = React.createRef(); - this.selectedElement = false; - this.state = { - diagram: false - }; this.versionChanged = false; } componentDidUpdate(prevProps) { @@ -146,7 +143,7 @@ class CompositionView extends Component { }); this.modeler.attachTo('#' + this.generatedId); - this.setDiagramToBPMN(composition ? composition : newDiagramXML); + this.setDiagramToBPMN(composition); this.modeler.on('element.out', () => this.exportDiagramToStore()); this.modeler.on('element.click', this.handleCompositionStatus); this.modeler.on( diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionActions.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionActions.js index b11c9567..fe74ba0d 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionActions.js +++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionActions.js @@ -13,13 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { SET_COMPOSITION, UPDATE_ERRORS } from './compositionConstants'; +import { + SET_COMPOSITION, + UPDATE_ERRORS, + DELETE_COMPOSITION +} from './compositionConstants'; export const updateComposition = payload => ({ type: SET_COMPOSITION, payload }); +export const deleteCompositionArtifact = () => ({ + type: DELETE_COMPOSITION +}); + export const updateValidation = payload => ({ type: UPDATE_ERRORS, payload diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js index 69c7fb86..1db40210 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js +++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionConstants.js @@ -14,6 +14,7 @@ * limitations under the License. */ export const SET_COMPOSITION = 'composition/SET_COMPOSITION'; +export const DELETE_COMPOSITION = 'composition/DELETE_COMPOSITION'; export const UPDATE_ERRORS = 'composition/UPDATE_ERRORS'; export const bpmnElementsTypes = { diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionReducer.js b/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionReducer.js index 53d9f444..9deb9cbd 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionReducer.js +++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/compositionReducer.js @@ -13,16 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { SET_COMPOSITION } from './compositionConstants'; +import { SET_COMPOSITION, DELETE_COMPOSITION } from './compositionConstants'; import { UPDATE_ERRORS } from './compositionConstants'; +import newDiagramXML from './newDiagram.bpmn'; -export default (state = { diagram: false, errors: [] }, action) => { +export default (state = { diagram: newDiagramXML, errors: [] }, action) => { switch (action.type) { case SET_COMPOSITION: return { ...state, diagram: action.payload }; + case DELETE_COMPOSITION: + return { + ...state, + diagram: newDiagramXML + }; case UPDATE_ERRORS: { const filteredErrors = state.errors.filter( item => item.element.id !== action.payload.element.id diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/composition/newDiagram.bpmn b/workflow-designer-ui/src/main/frontend/src/features/version/composition/newDiagram.bpmn index f54671c4..6abaf8df 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/version/composition/newDiagram.bpmn +++ b/workflow-designer-ui/src/main/frontend/src/features/version/composition/newDiagram.bpmn @@ -1,4 +1,4 @@ -export default `<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn"> <bpmn2:process id="Process_1" isExecutable="true"> </bpmn2:process> @@ -6,4 +6,4 @@ export default `<?xml version="1.0" encoding="UTF-8"?> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1"> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> -</bpmn2:definitions>`;
\ No newline at end of file +</bpmn2:definitions> diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/versionApi.js b/workflow-designer-ui/src/main/frontend/src/features/version/versionApi.js index ab9394cb..b3a2e13a 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/version/versionApi.js +++ b/workflow-designer-ui/src/main/frontend/src/features/version/versionApi.js @@ -66,6 +66,11 @@ const Api = { formData ); }, + deleteVersionArtifact: ({ workflowId, versionId }) => { + return RestfulAPIUtil.delete( + `${baseUrl(workflowId)}/${versionId}/artifact` + ); + }, certifyVersion: ({ workflowId, versionId }) => { return RestfulAPIUtil.post( `${baseUrl(workflowId)}/${versionId}/state`, diff --git a/workflow-designer-ui/src/main/frontend/src/features/version/versionSaga.js b/workflow-designer-ui/src/main/frontend/src/features/version/versionSaga.js index a7dabed8..a476b41e 100644 --- a/workflow-designer-ui/src/main/frontend/src/features/version/versionSaga.js +++ b/workflow-designer-ui/src/main/frontend/src/features/version/versionSaga.js @@ -33,27 +33,46 @@ import { notificationActions } from 'shared/notifications/notificationsActions'; import { versionState } from 'features/version/versionConstants'; import overviewApi from '../workflow/overview/overviewApi'; import { versionListFetchAction } from '../workflow/overview/overviewConstansts'; -import { updateComposition } from 'features/version/composition/compositionActions'; +import { + updateComposition, + deleteCompositionArtifact +} from 'features/version/composition/compositionActions'; import { getActivitiesList } from 'features/activities/activitiesActions'; +/** + * Composition validation - converting artifact string to xml + * and checking if bpmn diagram has only one child + * @param composition + * @returns {boolean} + */ +function validateCurrentArtifact(composition) { + const parser = new DOMParser(); + const xml = parser.parseFromString(composition, 'text/xml'); + return Boolean( + xml.getElementsByTagName('bpmndi:BPMNPlane').BPMNPlane_1.children.length + ); +} + function* fetchVersion(action) { try { yield put(getActivitiesList()); const data = yield call(versionApi.fetchVersion, action.payload); const { inputs, outputs, ...rest } = data; - let composition = false; + let composition; if (rest.hasArtifact) { composition = yield call( versionApi.fetchVersionArtifact, action.payload ); + } else { + //Clearing the store from old artifact using init the default + yield put(deleteCompositionArtifact()); } - yield all([ put(setWorkflowVersionAction(rest)), put(setInputsOutputs({ inputs, outputs })), - put(updateComposition(composition)) + composition && put(updateComposition(composition)) ]); } catch (error) { yield put(genericNetworkErrorAction(error)); @@ -81,12 +100,12 @@ function* watchUpdateVersion(action) { workflowName, params: { composition, ...versionData } } = action.payload; - - yield call(versionApi.updateVersion, { - workflowId, - params: versionData - }); - if (composition) { + const isArtifactValid = validateCurrentArtifact(composition); + if (isArtifactValid) { + yield call(versionApi.updateVersion, { + workflowId, + params: versionData + }); yield call(versionApi.updateVersionArtifact, { workflowId, workflowName, @@ -94,13 +113,21 @@ function* watchUpdateVersion(action) { versionId: versionData.id, payload: composition }); + yield put( + notificationActions.showSuccess({ + title: I18n.t('workflow.confirmationMessages.updateTitle'), + message: I18n.t( + 'workflow.confirmationMessages.updateMessage' + ) + }) + ); + } else { + yield call(versionApi.deleteVersionArtifact, { + workflowId, + versionId: versionData.id + }); } - yield put( - notificationActions.showSuccess({ - title: I18n.t('workflow.confirmationMessages.updateTitle'), - message: I18n.t('workflow.confirmationMessages.updateMessage') - }) - ); + return isArtifactValid; } catch (error) { yield put(genericNetworkErrorAction(error)); } @@ -108,18 +135,26 @@ function* watchUpdateVersion(action) { function* watchCertifyVersion(action) { try { - yield call(watchUpdateVersion, action); + const isArtifactValid = yield call(watchUpdateVersion, action); + if (!isArtifactValid) + throw new Error('Could not update empty artifact'); yield call(versionApi.certifyVersion, { ...action.payload }); + yield put(versionStateChangedAction({ state: versionState.CERTIFIED })); yield put( notificationActions.showSuccess({ title: I18n.t('workflow.confirmationMessages.certifyTitle'), message: I18n.t('workflow.confirmationMessages.certifyMessage') }) ); - yield put(versionStateChangedAction({ state: versionState.CERTIFIED })); } catch (error) { + yield put( + notificationActions.showError({ + title: I18n.t('workflow.confirmationMessages.certifyTitle'), + message: I18n.t('workflow.composition.certifyArtifact') + }) + ); yield put(genericNetworkErrorAction(error)); } } diff --git a/workflow-designer-ui/src/main/frontend/src/i18n/languages.json b/workflow-designer-ui/src/main/frontend/src/i18n/languages.json index b4c38266..9485681a 100644 --- a/workflow-designer-ui/src/main/frontend/src/i18n/languages.json +++ b/workflow-designer-ui/src/main/frontend/src/i18n/languages.json @@ -80,7 +80,8 @@ "bpmnError" : "BPMN.IO Error", "exportErrorMsg": "Could not export diagram", "saveErrorMsg": "Could not save diagram", - "importErrorMsg": "Could not import diagram" + "importErrorMsg": "Could not import diagram", + "certifyArtifact": "Could not certify empty artifact" }, "confirmationMessages": { "certifyTitle": "Certify Version", diff --git a/workflow-designer-ui/src/main/frontend/src/services/restAPIUtil.js b/workflow-designer-ui/src/main/frontend/src/services/restAPIUtil.js index 05c0d799..08262fed 100644 --- a/workflow-designer-ui/src/main/frontend/src/services/restAPIUtil.js +++ b/workflow-designer-ui/src/main/frontend/src/services/restAPIUtil.js @@ -136,7 +136,7 @@ class RestAPIUtil { return this.handleRequest(url, PUT, options, data); } - destroy(url, options) { + delete(url, options) { return this.handleRequest(url, DELETE, options); } |