summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cds-ui/designer-client/src/app/common/constants/app-constants.ts3
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html10
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts121
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts2
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts59
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions/functions.component.ts8
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/action.element.ts3
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/ModelType.model.ts (renamed from cds-ui/designer-client/src/app/modules/feature-modules/packages/model/ModelType.model.ts)0
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.dashboard.state.ts (renamed from cds-ui/designer-client/src/app/modules/feature-modules/packages/model/designer-dashboard.state.ts)9
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.topologyTemplate.model.ts13
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.workflow.ts14
-rw-r--r--cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/desinger.nodeTemplate.model.ts10
-rw-r--r--ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml4
-rwxr-xr-xms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt186
-rw-r--r--ms/blueprintsprocessor/modules/commons/processor-core/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/cluster/HazlecastClusterServiceTest.kt4
-rw-r--r--ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5679.yaml21
-rw-r--r--ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5680.yaml21
-rw-r--r--ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5681.yaml21
-rw-r--r--ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5682.yaml9
-rw-r--r--ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-cluster.yaml23
-rwxr-xr-xms/blueprintsprocessor/parent/pom.xml6
21 files changed, 380 insertions, 167 deletions
diff --git a/cds-ui/designer-client/src/app/common/constants/app-constants.ts b/cds-ui/designer-client/src/app/common/constants/app-constants.ts
index eeff3d41f..14cb001c8 100644
--- a/cds-ui/designer-client/src/app/common/constants/app-constants.ts
+++ b/cds-ui/designer-client/src/app/common/constants/app-constants.ts
@@ -118,3 +118,6 @@ export const ControllerCatalogURLs = {
getDefinition: '/controllercatalog/model-type/by-definition',
getDerivedFrom: '/controllercatalog/model-type/by-derivedfrom'
};
+
+
+export const ActionElementTypeName = 'app.ActionElement';
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
index 8ec735aec..311ce7ad9 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.html
@@ -61,20 +61,20 @@
[mode]="'push'"
#sidebarLeft>
<div class="row">
- <div class="col-12 p-0">
+ <!-- <div class="col-12 p-0">
<form>
<input type="text" class="form-control input-search-controller"
placeholder="Search actions and functions">
</form>
- </div>
+ </div> -->
<h1 class="col-12">Actions</h1>
<div class="col-12 text-center p-0">
<div class="btn-group actionBtns" role="group">
<button (click)="insertCustomActionIntoBoard()" type="button" class="btn">Insert Custom</button>
- <button type="button" class="btn">Import Action</button>
+ <!-- <button type="button" class="btn">Import Action</button> -->
</div>
</div>
- <div class="col-12 actionsList">
+ <!-- <div class="col-12 actionsList">
<b>Select from other packages:</b>
<div class="actions-scroll">
<div class="custom-control custom-checkbox">
@@ -106,7 +106,7 @@
<button type="button" class="btn btn-secondary mr-3">Insert</button>
<button type="button" class="btn btn-secondary">Cancel</button>
</div>
- </div>
+ </div> -->
<h1 class="col-12">Functions</h1>
<div id="palette-paper" class="col-12 componentsList">
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
index b19f5699b..130e0ae19 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.component.ts
@@ -3,6 +3,8 @@ import * as joint from 'jointjs';
import './jointjs/elements/palette.function.element';
import './jointjs/elements/action.element';
import './jointjs/elements/board.function.element';
+import { DesignerStore } from './designer.store';
+import { ActionElementTypeName } from 'src/app/common/constants/app-constants';
@@ -26,7 +28,7 @@ export class DesignerComponent implements OnInit {
paletteGraph: joint.dia.Graph;
palettePaper: joint.dia.Paper;
- constructor() {
+ constructor(private designerStore: DesignerStore) {
this.controllerSideBar = true;
this.attributesSideBar = false;
}
@@ -54,22 +56,37 @@ export class DesignerComponent implements OnInit {
this.initializeBoard();
this.initializePalette();
// this.createEditBarOverThePaper();
+
+ //functions list is contants for now
const list = [
{ modelName: 'component-netconf-executor'},
{ modelName: 'component-remote-ansible-executor' },
{ modelName: 'dg-generic' },
{ modelName: 'component-resource-resolution' }];
+ const cells = this.buildPaletteGraphFromList(list);
+ this.paletteGraph.resetCells(cells);
- const cells = this.buildPaletteGraphFromList(list);
- this.paletteGraph.resetCells(cells);
-
- let idx = 0;
- cells.forEach(cell => {
- console.log(cell);
- cell.translate(5, (cell.attributes.size.height + 5) * idx++);
+ let idx = 0;
+ cells.forEach(cell => {
+ console.log(cell);
+ cell.translate(5, (cell.attributes.size.height + 5) * idx++);
- });
- this.stencilPaperEventListeners();
+ });
+ this.stencilPaperEventListeners();
+ /**
+ * the code to retrieve from server is commented
+ */
+ // this.designerStore.state$.subscribe(state => {
+ // console.log(state);
+ // if (state.functions) {
+ // console.log('functions-->' , state.functions);
+ // // this.viewedFunctions = state.functions;
+ // const list = state.functions;
+ // }
+ // });
+ //action triggering
+ // this.designerStore.getFuntions();
+
}
initializePalette() {
@@ -127,9 +144,6 @@ export class DesignerComponent implements OnInit {
var parentBbox = parent.getBBox();
var cellBbox = cell.getBBox();
-
- console.log("parent ", parentBbox);
- console.log("cell ", cellBbox);
if (parentBbox.containsPoint(cellBbox.origin()) &&
parentBbox.containsPoint(cellBbox.topRight()) &&
parentBbox.containsPoint(cellBbox.corner()) &&
@@ -149,8 +163,12 @@ export class DesignerComponent implements OnInit {
insertCustomActionIntoBoard() {
this.actionIdCounter++;
- const element = this.createCustomAction("action_"+ this.actionIdCounter, 'Action' + this.actionIdCounter);
+ const actionId = "action_" + this.actionIdCounter;
+ const actionName = 'Action' + this.actionIdCounter;
+ const element = this.createCustomAction(actionId , actionName);
this.boardGraph.addCell(element);
+ console.log('saving action to store action workflow....');
+ this.designerStore.addDeclarativeWorkFlow(actionName);
}
createCustomAction(id: string, label: string) {
@@ -192,7 +210,6 @@ export class DesignerComponent implements OnInit {
stencilPaperEventListeners() {
this.palettePaper.on('cell:pointerdown', (draggedCell, pointerDownEvent, x, y) => {
- console.log('pointerdown 2');
$('body').append(`
<div id="flyPaper"
@@ -232,38 +249,30 @@ export class DesignerComponent implements OnInit {
if (mouseupX > target.left &&
mouseupX < target.left + this.boardPaper.$el.width() &&
mouseupY > target.top && y < target.top + this.boardPaper.$el.height()) {
- // const clonedShape = flyShape.clone();
- const type = flyShape.attributes.attrs.type;
- console.log(type);
-
- //create board function element of the same type of palette function
- //board function element is different in design from the palette function element
- this.fuctionIdCounter++;
- console.log(this.fuctionIdCounter);
- const functionElementForBoard =
- this.createFuctionElementForBoard("fucntion_" + this.fuctionIdCounter, 'execute', type);
-
- functionElementForBoard.position(mouseupX - target.left - offset.x, mouseupY - target.top - offset.y);
- this.boardGraph.addCell(functionElementForBoard);
- const cellViewsBelow =
- this.boardPaper.findViewsFromPoint(functionElementForBoard.getBBox().center());
- console.log(cellViewsBelow);
- if (cellViewsBelow.length) {
- let cellViewBelow;
- cellViewsBelow.forEach( cellItem => {
- if (cellItem.model.id !== functionElementForBoard.id) {
- cellViewBelow = cellItem;
- }
- });
+ const functionType = flyShape.attributes.attrs.type;
+ console.log(functionType);
+ const functionElementForBoard = this.dropFunctionOverAction(functionType, mouseupX, target, offset, mouseupY);
+
+ let parentCell = this.getParent(functionElementForBoard);
+
+ console.log("parentCell -->", parentCell);
+
+ if (parentCell &&
+ parentCell.model.attributes.type === ActionElementTypeName){
+
+ const actionName = parentCell.model.attributes.attrs['#label'].text;
+ this.designerStore.addStepToDeclarativeWorkFlow(actionName, functionType);
+ this.designerStore.addNodeTemplate(functionType);
// Prevent recursive embedding.
- if (cellViewBelow && cellViewBelow.model.get('parent') !== functionElementForBoard.id) {
- console.log(cellViewBelow);
- cellViewBelow.model.embed(functionElementForBoard);
+ if (parentCell &&
+ parentCell.model.get('parent') !== functionElementForBoard.id) {
+ parentCell.model.embed(functionElementForBoard);
}
- console.log(this.boardGraph);
+ }else{
+ console.log('function dropped outside action, rolling back...');
+ functionElementForBoard.remove();
}
-
}
$('body').off('mousemove.fly').off('mouseup.fly');
// flyShape.remove();
@@ -272,6 +281,32 @@ export class DesignerComponent implements OnInit {
});
}
+ private getParent(functionElementForBoard: joint.shapes.board.FunctionElement) {
+ const cellViewsBelow = this.boardPaper.findViewsFromPoint(functionElementForBoard.getBBox().center());
+ let cellViewBelow;
+ if (cellViewsBelow.length) {
+ cellViewsBelow.forEach(cellItem => {
+ if (cellItem.model.id !== functionElementForBoard.id) {
+ cellViewBelow = cellItem;
+ }
+ });
+ }
+ return cellViewBelow;
+ }
+
+ /**
+ * trigger actions related to Function dropped over the board:
+ * - create board function element of the same type of palette function
+ * as board function element is different from the palette function element
+ * - save function to parent action in store
+ */
+ private dropFunctionOverAction(functionType: any, mouseupX: number, target: JQuery.Coordinates, offset: { x: number; y: number; }, mouseupY: number) {
+ this.fuctionIdCounter++;
+ const functionElementForBoard = this.createFuctionElementForBoard("fucntion_" + this.fuctionIdCounter, 'execute', functionType);
+ functionElementForBoard.position(mouseupX - target.left - offset.x, mouseupY - target.top - offset.y);
+ this.boardGraph.addCell(functionElementForBoard);
+ return functionElementForBoard;
+ }
/**
* this is a way to add the button like zoom in , zoom out , and source over jointjs paper
* may be used if no other way is found
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts
index c4564254f..aa3a6a668 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.service.ts
@@ -23,7 +23,7 @@ import {Injectable} from '@angular/core';
import {Observable} from 'rxjs';
import {ApiService} from '../../../../common/core/services/api.typed.service';
import {ResourceDictionaryURLs} from '../../../../common/constants/app-constants';
-import {ModelType} from '../model/ModelType.model';
+import {ModelType} from './model/ModelType.model';
@Injectable({
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts
index be98eec88..f2972d03b 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/designer.store.ts
@@ -22,8 +22,10 @@ limitations under the License.
import {Injectable} from '@angular/core';
import {Store} from '../../../../common/core/stores/Store';
import {DesignerService} from './designer.service';
-import {ModelType} from '../model/ModelType.model';
-import {DesignerDashboardState} from '../model/designer-dashboard.state';
+import {ModelType} from './model/ModelType.model';
+import {DesignerDashboardState} from './model/designer.dashboard.state';
+import { DeclarativeWorkflow } from './model/designer.workflow';
+import { NodeTemplate } from './model/desinger.nodeTemplate.model';
@Injectable({
@@ -35,15 +37,60 @@ export class DesignerStore extends Store<DesignerDashboardState> {
super(new DesignerDashboardState());
}
- public getFuntions() {
+ public retrieveFuntions() {
const modelDefinitionType = 'node_type';
this.designerService.getFunctions(modelDefinitionType).subscribe(
- (modelType: ModelType[]) => {
- console.log(modelType);
+ (modelTypeList: ModelType[]) => {
+ console.log(modelTypeList);
this.setState({
...this.state,
- functions: modelType,
+ serverFunctions: modelTypeList,
});
});
}
+
+ /**
+ * adds empty workflow with name only.
+ * called when blank action is added to the board
+ * declarative workflow just contain the steps but its order is determind by dg-graph
+ */
+ addDeclarativeWorkFlow(workflowName: string) {
+ this.setState({
+ ...this.state,
+ template: {
+ ...this.state.template,
+ workflows:
+ this.state.template.workflows.set(workflowName, new DeclarativeWorkflow())
+ }
+ });
+ }
+
+ addStepToDeclarativeWorkFlow(workflowName: string, stepType: string) {
+ const currentWorkflow: DeclarativeWorkflow = this.state.template.workflows.get(workflowName);
+ currentWorkflow.steps = {
+ target: stepType,
+ description: ''
+ };
+ const allNewWorkflowsMap =
+ this.state.template.workflows.set(workflowName, currentWorkflow);
+ this.setState({
+ ...this.state,
+ template: {
+ ...this.state.template,
+ workflows: allNewWorkflowsMap
+ }
+ });
+ }
+
+
+ addNodeTemplate(nodeTemplateName: string) {
+ this.setState({
+ ...this.state,
+ template: {
+ ...this.state.template,
+ node_templates:
+ this.state.template.node_templates.set(nodeTemplateName, new NodeTemplate())
+ }
+ });
+ }
}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions/functions.component.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions/functions.component.ts
index 5a86150e8..e1e980ed9 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions/functions.component.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/functions/functions.component.ts
@@ -1,6 +1,6 @@
import {Component, OnInit} from '@angular/core';
import {DesignerStore} from '../designer.store';
-import {ModelType} from '../../model/ModelType.model';
+import {ModelType} from '../model/ModelType.model';
@Component({
@@ -15,14 +15,14 @@ export class FunctionsComponent implements OnInit {
this.designerStore.state$.subscribe(state => {
console.log(state);
- if (state.functions) {
- this.viewedFunctions = state.functions;
+ if (state.serverFunctions) {
+ this.viewedFunctions = state.serverFunctions;
}
});
}
ngOnInit() {
- this.designerStore.getFuntions();
+ this.designerStore.retrieveFuntions();
}
}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/action.element.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/action.element.ts
index 212905814..7960e83d1 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/action.element.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/jointjs/elements/action.element.ts
@@ -1,4 +1,5 @@
import * as joint from 'jointjs';
+import { ActionElementTypeName } from 'src/app/common/constants/app-constants';
/**
* please refer to documentation in file palette.function.element.ts to get more details
* about how to create new element type and define it in typescript
@@ -18,7 +19,7 @@ const rectWidth = 616;
const rectHeight = 381;
// custom element implementation
// https://resources.jointjs.com/tutorials/joint/tutorials/custom-elements.html#markup
-const ActionElement = joint.shapes.standard.Rectangle.define('app.ActionElement', {
+const ActionElement = joint.shapes.standard.Rectangle.define(ActionElementTypeName, {
size: {width: rectWidth, height: rectHeight}
},
{
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/ModelType.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/ModelType.model.ts
index c8498fa36..c8498fa36 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/ModelType.model.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/ModelType.model.ts
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/designer-dashboard.state.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.dashboard.state.ts
index dc65c009f..5ae62d84a 100644
--- a/cds-ui/designer-client/src/app/modules/feature-modules/packages/model/designer-dashboard.state.ts
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.dashboard.state.ts
@@ -20,10 +20,15 @@ limitations under the License.
*/
import {ModelType} from './ModelType.model';
+import { TopologyTemplate } from './designer.topologyTemplate.model';
export class DesignerDashboardState {
- functions: ModelType[];
- actions: string[];
+ serverFunctions: ModelType[];
+ template: TopologyTemplate;
+ constructor() {
+ this.serverFunctions = [];
+ this.template = new TopologyTemplate();
+ }
}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.topologyTemplate.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.topologyTemplate.model.ts
new file mode 100644
index 000000000..4e73c7986
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.topologyTemplate.model.ts
@@ -0,0 +1,13 @@
+import { DeclarativeWorkflow } from './designer.workflow';
+import { NodeTemplate } from './desinger.nodeTemplate.model';
+
+export class TopologyTemplate {
+
+ workflows: Map<string, DeclarativeWorkflow>;
+ 'node_templates': Map<string, NodeTemplate>;
+
+ constructor() {
+ this.workflows = new Map();
+ this.node_templates = new Map();
+ }
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.workflow.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.workflow.ts
new file mode 100644
index 000000000..0687c1f47
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/designer.workflow.ts
@@ -0,0 +1,14 @@
+export class Workflow {
+ inputs: {};
+ outputs?: {};
+}
+
+export class DeclarativeWorkflow implements Workflow {
+ steps: {};
+ inputs: {};
+ outputs?: {};
+
+ constructor() {
+ this.steps = {};
+ }
+}
diff --git a/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/desinger.nodeTemplate.model.ts b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/desinger.nodeTemplate.model.ts
new file mode 100644
index 000000000..7f8556535
--- /dev/null
+++ b/cds-ui/designer-client/src/app/modules/feature-modules/packages/designer/model/desinger.nodeTemplate.model.ts
@@ -0,0 +1,10 @@
+export class NodeTemplate {
+ type: string;
+ properties?: {
+ 'dependency-node-template'?: string[]
+ };
+ interfaces?: {};
+ artifacts?: {};
+ cabapilities?: {};
+ requirements?: {};
+}
diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml
index 28060ef44..fb2daab3a 100644
--- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml
+++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/pom.xml
@@ -91,6 +91,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ </dependency>
<!--Testing dependencies-->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
diff --git a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt
index 9ccf856b5..595dbce6b 100755
--- a/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt
+++ b/ms/blueprintsprocessor/modules/blueprints/blueprint-core/src/main/kotlin/org/onap/ccsdk/cds/controllerblueprints/core/utils/BluePrintArchiveUtils.kt
@@ -22,22 +22,39 @@ import com.google.common.base.Predicates
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
import org.slf4j.LoggerFactory
import java.io.BufferedInputStream
+import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
+import java.io.Closeable
import java.io.File
import java.io.FileOutputStream
+import java.io.InputStream
+import java.io.InputStreamReader
import java.io.IOException
import java.io.OutputStream
-import java.nio.charset.Charset
import java.nio.file.FileVisitResult
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.SimpleFileVisitor
import java.nio.file.attribute.BasicFileAttributes
import java.util.function.Predicate
+import org.apache.commons.compress.archivers.ArchiveEntry
+import org.apache.commons.compress.archivers.ArchiveInputStream
+import org.apache.commons.compress.archivers.ArchiveOutputStream
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
+import org.apache.commons.compress.archivers.zip.ZipFile
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream
+import java.util.Enumeration
import java.util.zip.Deflater
-import java.util.zip.ZipEntry
-import java.util.zip.ZipFile
-import java.util.zip.ZipOutputStream
+
+enum class ArchiveType {
+ TarGz,
+ Zip
+}
class BluePrintArchiveUtils {
@@ -51,7 +68,7 @@ class BluePrintArchiveUtils {
* @param destination the output filename
* @return True if OK
*/
- fun compress(source: File, destination: File): Boolean {
+ fun compress(source: File, destination: File, archiveType: ArchiveType = ArchiveType.Zip): Boolean {
try {
if (!destination.parentFile.exists()) {
destination.parentFile.mkdirs()
@@ -59,7 +76,7 @@ class BluePrintArchiveUtils {
destination.createNewFile()
val ignoreZipFiles = Predicate<Path> { path -> !path.endsWith(".zip") && !path.endsWith(".ZIP") }
FileOutputStream(destination).use { out ->
- compressFolder(source.toPath(), out, pathFilter = ignoreZipFiles)
+ compressFolder(source.toPath(), out, archiveType, pathFilter = ignoreZipFiles)
}
} catch (e: Exception) {
log.error("Fail to compress folder($source) to path(${destination.path})", e)
@@ -71,8 +88,12 @@ class BluePrintArchiveUtils {
/**
* In-memory compress an entire folder.
*/
- fun compressToBytes(baseDir: Path, compressionLevel: Int = Deflater.NO_COMPRESSION): ByteArray {
- return compressFolder(baseDir, ByteArrayOutputStream(), compressionLevel = compressionLevel)
+ fun compressToBytes(
+ baseDir: Path,
+ archiveType: ArchiveType = ArchiveType.Zip,
+ compressionLevel: Int = Deflater.NO_COMPRESSION
+ ): ByteArray {
+ return compressFolder(baseDir, ByteArrayOutputStream(), archiveType, compressionLevel = compressionLevel)
.toByteArray()
}
@@ -89,38 +110,51 @@ class BluePrintArchiveUtils {
private fun <T> compressFolder(
baseDir: Path,
output: T,
+ archiveType: ArchiveType,
pathFilter: Predicate<Path> = Predicates.alwaysTrue(),
compressionLevel: Int = Deflater.DEFAULT_COMPRESSION,
fixedModificationTime: Long? = null
): T
where T : OutputStream {
- ZipOutputStream(output)
- .apply { setLevel(compressionLevel) }
- .use { zos ->
+ val stream: ArchiveOutputStream = if (archiveType == ArchiveType.Zip)
+ ZipArchiveOutputStream(output).apply { setLevel(compressionLevel) }
+ else
+ TarArchiveOutputStream(GzipCompressorOutputStream(output))
+ stream
+ .use { aos ->
Files.walkFileTree(baseDir, object : SimpleFileVisitor<Path>() {
@Throws(IOException::class)
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
if (pathFilter.test(file)) {
- val zipEntry = ZipEntry(baseDir.relativize(file).toString())
- fixedModificationTime?.let {
- zipEntry.time = it
+ var archiveEntry: ArchiveEntry = aos.createArchiveEntry(file.toFile(),
+ baseDir.relativize(file).toString())
+ if (archiveType == ArchiveType.Zip) {
+ val entry = archiveEntry as ZipArchiveEntry
+ fixedModificationTime?.let {
+ entry.time = it
+ }
+ entry.time = 0
}
- zipEntry.time = 0
- zos.putNextEntry(zipEntry)
- Files.copy(file, zos)
- zos.closeEntry()
+ aos.putArchiveEntry(archiveEntry)
+ Files.copy(file, aos)
+ aos.closeArchiveEntry()
}
return FileVisitResult.CONTINUE
}
@Throws(IOException::class)
override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
- val zipEntry = ZipEntry(baseDir.relativize(dir).toString() + "/")
- fixedModificationTime?.let {
- zipEntry.time = it
- }
- zos.putNextEntry(zipEntry)
- zos.closeEntry()
+ var archiveEntry: ArchiveEntry?
+ if (archiveType == ArchiveType.Zip) {
+ val entry = ZipArchiveEntry(baseDir.relativize(dir).toString() + "/")
+ fixedModificationTime?.let {
+ entry.time = it
+ }
+ archiveEntry = entry
+ } else
+ archiveEntry = TarArchiveEntry(baseDir.relativize(dir).toString() + "/")
+ aos.putArchiveEntry(archiveEntry)
+ aos.closeArchiveEntry()
return FileVisitResult.CONTINUE
}
})
@@ -128,31 +162,111 @@ class BluePrintArchiveUtils {
return output
}
- fun deCompress(zipFile: File, targetPath: String): File {
- val zip = ZipFile(zipFile, Charset.defaultCharset())
- val enumeration = zip.entries()
- while (enumeration.hasMoreElements()) {
- val entry = enumeration.nextElement()
- val destFilePath = File(targetPath, entry.name)
- destFilePath.parentFile.mkdirs()
+ private fun getDefaultEncoding(): String? {
+ val bytes = byteArrayOf('D'.toByte())
+ val inputStream: InputStream = ByteArrayInputStream(bytes)
+ val reader = InputStreamReader(inputStream)
+ return reader.encoding
+ }
- if (entry.isDirectory)
- continue
+ fun deCompress(archiveFile: File, targetPath: String, archiveType: ArchiveType = ArchiveType.Zip): File {
+ var enumeration: ArchiveEnumerator? = null
+ if (archiveType == ArchiveType.Zip) {
+ val zipArchive = ZipFile(archiveFile, getDefaultEncoding())
+ enumeration = ArchiveEnumerator(zipArchive)
+ } else { // Tar Gz
+ var tarGzArchiveIs: InputStream = BufferedInputStream(archiveFile.inputStream())
+ tarGzArchiveIs = GzipCompressorInputStream(tarGzArchiveIs)
+ val tarGzArchive: ArchiveInputStream = TarArchiveInputStream(tarGzArchiveIs)
+ enumeration = ArchiveEnumerator(tarGzArchive)
+ }
+
+ enumeration.use {
+ while (enumeration!!.hasMoreElements()) {
+ val entry: ArchiveEntry? = enumeration.nextElement()
+ val destFilePath = File(targetPath, entry!!.name)
+ destFilePath.parentFile.mkdirs()
- val bufferedIs = BufferedInputStream(zip.getInputStream(entry))
- bufferedIs.use {
+ if (entry!!.isDirectory)
+ continue
+
+ val bufferedIs = BufferedInputStream(enumeration.getInputStream(entry))
destFilePath.outputStream().buffered(1024).use { bos ->
bufferedIs.copyTo(bos)
}
+
+ if (!enumeration.getHasSharedEntryInputStream())
+ bufferedIs.close()
}
}
val destinationDir = File(targetPath)
check(destinationDir.isDirectory && destinationDir.exists()) {
- throw BluePrintProcessorException("failed to decompress blueprint(${zipFile.absolutePath}) to ($targetPath) ")
+ throw BluePrintProcessorException("failed to decompress blueprint(${archiveFile.absolutePath}) to ($targetPath) ")
}
return destinationDir
}
}
+
+ class ArchiveEnumerator : Enumeration<ArchiveEntry>, Closeable {
+ private val zipArchive: ZipFile?
+ private val zipEnumeration: Enumeration<ZipArchiveEntry>?
+ private val archiveStream: ArchiveInputStream?
+ private var nextEntry: ArchiveEntry? = null
+ private val hasSharedEntryInputStream: Boolean
+
+ constructor(zipFile: ZipFile) {
+ zipArchive = zipFile
+ zipEnumeration = zipFile.entries
+ archiveStream = null
+ hasSharedEntryInputStream = false
+ }
+
+ constructor(archiveStream: ArchiveInputStream) {
+ this.archiveStream = archiveStream
+ zipArchive = null
+ zipEnumeration = null
+ hasSharedEntryInputStream = true
+ }
+
+ fun getHasSharedEntryInputStream(): Boolean {
+ return hasSharedEntryInputStream
+ }
+
+ fun getInputStream(entry: ArchiveEntry): InputStream? {
+ return if (zipArchive != null)
+ zipArchive?.getInputStream(entry as ZipArchiveEntry?)
+ else
+ archiveStream
+ }
+
+ override fun hasMoreElements(): Boolean {
+ if (zipEnumeration != null)
+ return zipEnumeration?.hasMoreElements()
+ else if (archiveStream != null) {
+ nextEntry = archiveStream.nextEntry
+ if (nextEntry != null && !archiveStream.canReadEntryData(nextEntry))
+ return hasMoreElements()
+ return nextEntry != null
+ }
+ return false
+ }
+
+ override fun nextElement(): ArchiveEntry? {
+ if (zipEnumeration != null)
+ nextEntry = zipEnumeration.nextElement()
+ else if (archiveStream != null) {
+ if (nextEntry == null)
+ nextEntry = archiveStream.nextEntry
+ }
+ return nextEntry
+ }
+
+ override fun close() {
+ if (zipArchive != null)
+ zipArchive.close()
+ else archiveStream?.close()
+ }
+ }
}
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/cluster/HazlecastClusterServiceTest.kt b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/cluster/HazlecastClusterServiceTest.kt
index b298eacae..80cf41558 100644
--- a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/cluster/HazlecastClusterServiceTest.kt
+++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/core/cluster/HazlecastClusterServiceTest.kt
@@ -113,7 +113,7 @@ class HazlecastClusterServiceTest {
} else {
ClusterInfo(
id = "test-cluster", nodeId = nodeId, joinAsClient = false,
- configFile = "./src/test/resources/hazelcast/hazelcast-$port.yaml",
+ configFile = "./src/test/resources/hazelcast/hazelcast-cluster.yaml",
properties = properties
)
}
@@ -162,7 +162,7 @@ class HazlecastClusterServiceTest {
executeLock(bluePrintClusterServices[0], "first", lockName)
}
val deferred2 = async {
- executeLock(bluePrintClusterServices[0], "second", lockName)
+ executeLock(bluePrintClusterServices[1], "second", lockName)
}
val deferred3 = async {
executeLock(bluePrintClusterServices[2], "third", lockName)
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5679.yaml b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5679.yaml
deleted file mode 100644
index e7ac273ed..000000000
--- a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5679.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-hazelcast:
- cluster-name: ${CLUSTER_ID}
- instance-name: node-5679
- lite-member:
- enabled: false
- cp-subsystem:
- cp-member-count: 3
- group-size: 3
- session-time-to-live-seconds: 60
- session-heartbeat-interval-seconds: 5
- missing-cp-member-auto-removal-seconds: 120
-# network:
-# join:
-# multicast:
-# enabled: false
-# kubernetes:
-# enabled: true
-# namespace: MY-KUBERNETES-NAMESPACE
-# service-name: MY-SERVICE-NAME
-# service-label-name: MY-SERVICE-LABEL-NAME
-# service-label-value: MY-SERVICE-LABEL-VALUE \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5680.yaml b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5680.yaml
deleted file mode 100644
index cb493d169..000000000
--- a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5680.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-hazelcast:
- cluster-name: ${CLUSTER_ID}
- instance-name: node-5680
- lite-member:
- enabled: false
- cp-subsystem:
- cp-member-count: 3
- group-size: 3
- session-time-to-live-seconds: 60
- session-heartbeat-interval-seconds: 5
- missing-cp-member-auto-removal-seconds: 120
-# network:
-# join:
-# multicast:
-# enabled: false
-# kubernetes:
-# enabled: true
-# namespace: MY-KUBERNETES-NAMESPACE
-# service-name: MY-SERVICE-NAME
-# service-label-name: MY-SERVICE-LABEL-NAME
-# service-label-value: MY-SERVICE-LABEL-VALUE \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5681.yaml b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5681.yaml
deleted file mode 100644
index e60b0c506..000000000
--- a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5681.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-hazelcast:
- cluster-name: ${CLUSTER_ID}
- instance-name: node-5681
- lite-member:
- enabled: false
- cp-subsystem:
- cp-member-count: 3
- group-size: 3
- session-time-to-live-seconds: 60
- session-heartbeat-interval-seconds: 5
- missing-cp-member-auto-removal-seconds: 120
-# network:
-# join:
-# multicast:
-# enabled: false
-# kubernetes:
-# enabled: true
-# namespace: MY-KUBERNETES-NAMESPACE
-# service-name: MY-SERVICE-NAME
-# service-label-name: MY-SERVICE-LABEL-NAME
-# service-label-value: MY-SERVICE-LABEL-VALUE \ No newline at end of file
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5682.yaml b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5682.yaml
index 3cb10a08b..859ea3328 100644
--- a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5682.yaml
+++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-5682.yaml
@@ -9,10 +9,11 @@ hazelcast:
session-time-to-live-seconds: 60
session-heartbeat-interval-seconds: 5
missing-cp-member-auto-removal-seconds: 120
-# network:
-# join:
-# multicast:
-# enabled: false
+ network:
+ join:
+ multicast:
+ enabled: true
+ multicast-group: 224.0.0.1
# kubernetes:
# enabled: true
# namespace: MY-KUBERNETES-NAMESPACE
diff --git a/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-cluster.yaml b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-cluster.yaml
new file mode 100644
index 000000000..de6047a90
--- /dev/null
+++ b/ms/blueprintsprocessor/modules/commons/processor-core/src/test/resources/hazelcast/hazelcast-cluster.yaml
@@ -0,0 +1,23 @@
+hazelcast:
+ lite-member:
+ enabled: false
+ cp-subsystem:
+ cp-member-count: 3
+ group-size: 3
+ session-time-to-live-seconds: 60
+ session-heartbeat-interval-seconds: 5
+ missing-cp-member-auto-removal-seconds: 120
+ network:
+ join:
+ multicast:
+ enabled: true
+ # Specify 224.0.0.1 instead of default 224.2.2.3 since there's some issue
+ # on macOs with docker installed and multicast address different than 224.0.0.1
+ # https://stackoverflow.com/questions/46341715/hazelcast-multicast-does-not-work-because-of-vboxnet-which-is-used-by-docker-mac
+ multicast-group: 224.0.0.1
+ # kubernetes:
+ # enabled: true
+ # namespace: MY-KUBERNETES-NAMESPACE
+ # service-name: MY-SERVICE-NAME
+ # service-label-name: MY-SERVICE-LABEL-NAME
+ # service-label-value: MY-SERVICE-LABEL-VALUE
diff --git a/ms/blueprintsprocessor/parent/pom.xml b/ms/blueprintsprocessor/parent/pom.xml
index 8301fbccf..d47889a48 100755
--- a/ms/blueprintsprocessor/parent/pom.xml
+++ b/ms/blueprintsprocessor/parent/pom.xml
@@ -60,6 +60,7 @@
<json-smart.version>2.3</json-smart.version>
<commons-io-version>2.6</commons-io-version>
+ <commons-compress-version>1.20</commons-compress-version>
<commons-collections-version>3.2.2</commons-collections-version>
</properties>
@@ -130,6 +131,11 @@
<version>${commons-io-version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-compress</artifactId>
+ <version>${commons-compress-version}</version>
+ </dependency>
+ <dependency>
<groupId>com.hubspot.jinjava</groupId>
<artifactId>jinjava</artifactId>
<version>${jinja.version}</version>