Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ingest] - Error handling from simulate API #6675

Merged
merged 11 commits into from
Apr 7, 2016
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ app.directive('outputPreview', function () {
template: outputPreviewTemplate,
scope: {
oldObject: '=',
newObject: '='
newObject: '=',
error: '='
},
link: function ($scope, $el) {
const div = $el.find('.visual')[0];
Expand All @@ -27,10 +28,10 @@ app.directive('outputPreview', function () {
});

$scope.updateUi = function () {
const left = $scope.oldObject;
const right = $scope.newObject;
let left = $scope.oldObject;
let right = $scope.newObject;
let delta = $scope.diffpatch.diff(left, right);
if (!delta) delta = {};
if (!delta || $scope.error) delta = {};

div.innerHTML = htmlFormat(delta, left);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ app.directive('pipelineSetup', function () {

//initiates the simulate call if the pipeline is dirty
const simulatePipeline = debounce((event, message) => {
if (!pipeline.dirty) return;

if (pipeline.processors.length === 0) {
pipeline.updateOutput();
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import './processor_ui_container';
import './processor_ui_gsub';
import './processor_ui_set';
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import uiModules from 'ui/modules';
import _ from 'lodash';
import keysDeep from '../lib/keys_deep';
import template from '../views/processor_ui_gsub.html';

const app = uiModules.get('kibana');

//scope.processor, scope.pipeline are attached by the process_container.
app.directive('processorUiGsub', function () {
return {
restrict: 'E',
template: template,
controller : function ($scope) {
const processor = $scope.processor;
const pipeline = $scope.pipeline;

function consumeNewInputObject() {
$scope.fields = keysDeep(processor.inputObject);
refreshFieldData();
}

function refreshFieldData() {
$scope.fieldData = _.get(processor.inputObject, processor.sourceField);
}

function processorUiChanged() {
pipeline.setDirty();
}

$scope.$watch('processor.inputObject', consumeNewInputObject);

$scope.$watch('processor.sourceField', () => {
refreshFieldData();
processorUiChanged();
});

$scope.$watch('processor.pattern', processorUiChanged);
$scope.$watch('processor.replacement', processorUiChanged);
}
};
});
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import uiModules from 'ui/modules';
import processorUiSetTemplate from '../views/processor_ui_set.html';
import template from '../views/processor_ui_set.html';

const app = uiModules.get('kibana');

//scope.processor, scope.pipeline are attached by the process_container.
app.directive('processorUiSet', function () {
return {
restrict: 'E',
template: processorUiSetTemplate,
template: template,
controller : function ($scope) {
const processor = $scope.processor;
const pipeline = $scope.pipeline;

function processorUiChanged() {
pipeline.dirty = true;
pipeline.setDirty();
}

$scope.$watch('processor.targetField', processorUiChanged);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ app.directive('sourceData', function () {
restrict: 'E',
scope: {
samples: '=',
sample: '='
sample: '=',
disabled: '='
},
template: sourceDataTemplate,
controller: function ($scope) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ describe('processor pipeline', function () {
pipeline.processors[0].model = { bar: 'baz' };

const actual = pipeline.model;
const expected = { input: pipeline.input, processors: [ pipeline.processors[0].model ]};
const expected = {
input: pipeline.input,
processors: [ pipeline.processors[0].model ]
};

expect(actual).to.eql(expected);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,76 @@
import _ from 'lodash';

function updateProcessorOutputs(pipeline, simulateResults) {
simulateResults.forEach((result) => {
const processor = pipeline.getProcessorById(result.processorId);

processor.outputObject = _.get(result, 'output');
processor.error = _.get(result, 'error');
});
}

//Updates the error state of the pipeline and its processors
//If a pipeline compile error is returned, lock all processors but the error
//If a pipeline data error is returned, lock all processors after the error
function updateErrorState(pipeline) {
pipeline.hasCompileError = _.some(pipeline.processors, (processor) => {
return _.get(processor, 'error.compile');
});
_.forEach(pipeline.processors, processor => {
processor.locked = false;
});

const errorIndex = _.findIndex(pipeline.processors, 'error');
if (errorIndex === -1) return;

_.forEach(pipeline.processors, (processor, index) => {
if (pipeline.hasCompileError && index !== errorIndex) {
processor.locked = true;
}
if (!pipeline.hasCompileError && index > errorIndex) {
processor.locked = true;
}
});
}

function updateProcessorInputs(pipeline) {
pipeline.processors.forEach((processor) => {
//we don't want to change the inputObject if the parent processor
//is in error because that can cause us to lose state.
if (!_.get(processor, 'parent.error')) {
//the parent property of the first processor is set to the pipeline.input.
//In all other cases it is set to processor[index-1]
if (!processor.parent.processorId) {
processor.inputObject = _.cloneDeep(processor.parent);
} else {
processor.inputObject = _.cloneDeep(processor.parent.outputObject);
}
}
});
}


export default class Pipeline {

constructor() {
this.processors = [];
this.counter = 0;
this.processorCounter = 0;
this.input = {};
this.output = undefined;
this.dirty = false;
this.hasCompileError = false;
}

get model() {
return {
const pipeline = {
input: this.input,
processors: _.map(this.processors, processor => processor.model)
};
return pipeline;
}

setDirty() {
this.dirty = true;
}

load(pipeline) {
Expand Down Expand Up @@ -64,8 +120,8 @@ export default class Pipeline {
add(ProcessorType) {
const processors = this.processors;

this.counter += 1;
const processorId = `processor_${this.counter}`;
this.processorCounter += 1;
const processorId = `processor_${this.processorCounter}`;
const newProcessor = new ProcessorType(processorId);
processors.push(newProcessor);

Expand All @@ -88,16 +144,6 @@ export default class Pipeline {
this.dirty = true;
}

updateOutput() {
const processors = this.processors;

this.output = undefined;
if (processors.length > 0) {
this.output = processors[processors.length - 1].outputObject;
}
this.dirty = false;
}

getProcessorById(processorId) {
const result = _.find(this.processors, { processorId });

Expand All @@ -108,34 +154,22 @@ export default class Pipeline {
return result;
}

// Updates the state of the pipeline and processors with the results
// from an ingest simulate call.
applySimulateResults(results) {
//update the outputObject of each processor
results.forEach((result) => {
const processor = this.getProcessorById(result.processorId);

processor.outputObject = _.get(result, 'output');
processor.error = _.get(result, 'error');
});
updateOutput() {
const processors = this.processors;

//update the inputObject of each processor
results.forEach((result) => {
const processor = this.getProcessorById(result.processorId);

//we don't want to change the inputObject if the parent processor
//is in error because that can cause us to lose state.
if (!_.get(processor, 'error.isNested')) {
//the parent property of the first processor is set to the pipeline.input.
//In all other cases it is set to processor[index-1]
if (!processor.parent.processorId) {
processor.inputObject = _.cloneDeep(processor.parent);
} else {
processor.inputObject = _.cloneDeep(processor.parent.outputObject);
}
}
});
this.output = undefined;
if (processors.length > 0) {
this.output = processors[processors.length - 1].outputObject;
}
this.dirty = false;
}

// Updates the state of the pipeline and processors with the results
// from an ingest simulate call.
applySimulateResults(simulateResults) {
updateProcessorOutputs(this, simulateResults);
updateErrorState(this);
updateProcessorInputs(this);
this.updateOutput();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,30 @@ class Processor {
}
}

export class Gsub extends Processor {
constructor(processorId) {
super(processorId, 'gsub', 'Gsub');
this.sourceField = '';
this.pattern = '';
this.replacement = '';
}

get description() {
const source = this.sourceField || '?';
return `[${source}] - /${this.pattern}/ -> '${this.replacement}'`;
}

get model() {
return {
processorId: this.processorId,
typeId: this.typeId,
sourceField: this.sourceField || '',
pattern: this.pattern || '',
replacement: this.replacement || ''
};
}
};

export class Set extends Processor {
constructor(processorId) {
super(processorId, 'set', 'Set');
Expand All @@ -38,8 +62,8 @@ export class Set extends Processor {
return {
processorId: this.processorId,
typeId: this.typeId,
targetField: this.targetField,
value: this.value
targetField: this.targetField || '',
value: this.value || ''
};
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ processor-ui-container {
background-color: @settings-pipeline-setup-processor-container-overlay-bg;
}

&.dirty {
&.locked {
.overlay {
display: block;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<source-data sample="sample" samples="samples"></source-data>
<source-data sample="sample" samples="samples" disabled="pipeline.hasCompileError"></source-data>

<pipeline-output pipeline="pipeline"></pipeline-output>

Expand Down Expand Up @@ -28,6 +28,6 @@
</div>
<button
ng-click="pipeline.add(processorType.Type)"
ng-disabled="!processorType">
ng-disabled="!processorType || pipeline.hasCompileError">
Add Processor
</button>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</processor-ui-container-header>
<div
class="processor-ui-container-body"
ng-class="{dirty: processor.error.isNested}">
ng-class="{locked: processor.locked}">
<div
class="processor-ui-container-body-content"
ng-hide="processor.collapsed">
Expand All @@ -15,7 +15,11 @@
{{processor.error.message}}
</div>
<div class="processor-ui-content"></div>
<output-preview new-object="processor.outputObject" old-object="processor.inputObject"></output-preview>
<output-preview
new-object="processor.outputObject"
old-object="processor.inputObject"
error="processor.error">
</output-preview>
</div>
<div class="overlay"></div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
tooltip-append-to-body="true"
ng-click="pipeline.moveUp(processor)"
type="button"
class="btn btn-xs btn-default">
class="btn btn-xs btn-default"
ng-disabled="pipeline.hasCompileError">
<i aria-hidden="true" class="fa fa-caret-up"></i>
</button>

Expand All @@ -41,7 +42,8 @@
tooltip-append-to-body="true"
ng-click="pipeline.moveDown(processor)"
type="button"
class="btn btn-xs btn-default">
class="btn btn-xs btn-default"
ng-disabled="pipeline.hasCompileError">
<i aria-hidden="true" class="fa fa-caret-down"></i>
</button>

Expand All @@ -51,7 +53,8 @@
tooltip-append-to-body="true"
ng-click="pipeline.remove(processor)"
type="button"
class="btn btn-xs btn-danger">
class="btn btn-xs btn-danger"
ng-disabled="pipeline.hasCompileError && !processor.error">
<i aria-hidden="true" class="fa fa-times"></i>
</button>
</div>
Expand Down
Loading