blob: 1f54756806a4932ff8e95f45f49ea21c4816e701 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function () {
'use strict';
/***
* @ngdoc controller
* @name app.controllers.feed.FeedController
* @requires EntityModel the entity model to copy the feed entity from
* @requires Falcon the falcon service to talk with the Falcon REST API
*/
var clusterModule = angular.module('app.controllers.cluster', [ 'app.services' ]);
clusterModule.controller('ClusterFormCtrl', [
"$scope", "$interval", "Falcon", "EntityModel", "$state", "FileApi", "X2jsService", "ValidationService",
"SpinnersFlag", "$timeout", "$rootScope", "$cookieStore", "$stateParams", "ClusterModel",
function ($scope, $interval, Falcon, EntityModel, $state, FileApi, X2jsService, validationService,
SpinnersFlag, $timeout, $rootScope, $cookieStore, $stateParams, clusterModel) {
if (clusterModel && $stateParams.action === 'clone') {
$scope.cloningMode = true;
$scope.editingMode = false;
$scope.clusterEntity = { 'clusterModel' : clusterModel };
$scope.clusterEntity.clusterModel.name = "";
} else if(clusterModel && $stateParams.action === 'edit') {
$scope.editingMode = true;
$scope.cloningMode = false;
$scope.clusterEntity = { 'clusterModel' : clusterModel };
} else{
$scope.editingMode = false;
$scope.cloningMode = false;
$scope.clusterEntity = EntityModel;
}
if ($rootScope.secureMode) {
$scope.clusterEntity.clusterModel.cluster.properties.property[0]
= {_name : 'dfs.namenode.kerberos.principal', _value : 'nn/_HOST@EXAMPLE.COM'}
}
$scope.$watch("clusterEntity.clusterModel.cluster._name",function(){
if ($scope.editingMode) {
return;
}
$scope.clusterEntity.clusterModel.cluster.locations.location.forEach (function(loc, index) {
if (loc._name === "staging") {
loc._path = "/apps/falcon/"
+ ($scope.clusterEntity.clusterModel.cluster._name ? $scope.clusterEntity.clusterModel.cluster._name + "/" : "")
+ "staging";
} else if (loc._name === "working") {
loc._path = "/apps/falcon/"
+ ($scope.clusterEntity.clusterModel.cluster._name ? $scope.clusterEntity.clusterModel.cluster._name + "/" : "")
+ "working";
}
});
});
$scope.xmlPreview = { edit: false };
$scope.secondStep = false;
$scope.enableCustomSparkInterface = function() {
$scope.customSparkInterfaceEnabled = !$scope.customSparkInterfaceEnabled;
}
function normalizeModel() {
//------------INTERFACE-----------//
var requiredInterfaceFields = ["readonly", "write", "execute", "workflow", "messaging", "registry", "spark"],
requiredLocationFields = ["staging", "temp", "working"],
modelInterfaceArray = $scope.clusterEntity.clusterModel.cluster.interfaces.interface,
modelLocationsArray = $scope.clusterEntity.clusterModel.cluster.locations.location;
modelInterfaceArray.forEach(function (element) {
requiredInterfaceFields.forEach(function (requiredField) {
if (element._type === requiredField) { requiredInterfaceFields.splice(requiredField, 1); }
});
});
$scope.registry = { check: false };
$scope.spark = { check: false };
$scope.customSparkInterfaceEnabled = false;
requiredInterfaceFields.forEach(function (fieldToPush) {
var fieldObject = { _type: fieldToPush, _endpoint: "", _version: "" };
//if (fieldToPush === "registry") { $scope.registry = { check: true }; }
modelInterfaceArray.push(fieldObject);
});
//--------------TAGS--------------//
if ($scope.clusterEntity.clusterModel.cluster.tags === "" ||
$scope.clusterEntity.clusterModel.cluster.tags === undefined) {
$scope.clusterEntity.clusterModel.cluster.tags = "";
$scope.tagsArray = [{key: null, value: null}];
} else {
$scope.splitTags();
}
//-------------ACL----------------//
if (!$scope.clusterEntity.clusterModel.cluster.ACL) {
angular.copy(EntityModel.defaultValues.cluster.cluster.ACL, $scope.clusterEntity.clusterModel.cluster.ACL);
/*$scope.clusterEntity.clusterModel.cluster.ACL = {
_owner: "", _group: "", _permission: ""
};*/
}
if ($cookieStore.get('userToken') && !$scope.clusterEntity.clusterModel.cluster.ACL._owner) {
$scope.clusterEntity.clusterModel.cluster.ACL._owner = $cookieStore.get('userToken').user;
}
//------------Location------------//
modelLocationsArray.forEach(function(element) {
requiredLocationFields.forEach(function(requiredField, index) {
if(element._name === requiredField) { requiredLocationFields.splice(index, 1); }
});
});
requiredLocationFields.forEach(function(fieldToPush) {
var fieldObject = {_name: fieldToPush, _path: ""};
modelLocationsArray.push(fieldObject);
});
//----------Properties -------------//
if(!$scope.clusterEntity.clusterModel.cluster.properties) {
$scope.clusterEntity.clusterModel.cluster.properties = { property : [{ _name: "", _value: ""}] };
}
}
function cleanModel() {
if (!$scope.clusterEntity.clusterModel.cluster._description) {
$scope.clusterEntity.clusterModel.cluster._description = '';
}
//if registry check is false backups the object and removes it from array
if ($scope.registry && !$scope.registry.check) {
$scope.clusterEntity.clusterModel.cluster.interfaces.interface.forEach(function(registry, index) {
if (registry._type === "registry") {
$scope.backupRegistryObject = $scope.clusterEntity.clusterModel.cluster.interfaces.interface[index];
$scope.clusterEntity.clusterModel.cluster.interfaces.interface.splice(index, 1);
}
});
}
if ($scope.spark && !$scope.spark.check) {
$scope.clusterEntity.clusterModel.cluster.interfaces.interface.forEach(function(spark, index) {
if (spark._type === "spark") {
$scope.backupSparkObject = $scope.clusterEntity.clusterModel.cluster.interfaces.interface[index];
$scope.clusterEntity.clusterModel.cluster.interfaces.interface.splice(index, 1);
}
});
}
//deletes property empty last object and array if empty
if($scope.clusterEntity.clusterModel.cluster.properties){
var lastOne = $scope.clusterEntity.clusterModel.cluster.properties.property.length - 1;
if (
$scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._name === "" ||
$scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._name === undefined ||
$scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._value === "" ||
$scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._value === undefined
) {
$scope.removeProperty(lastOne);
}
if ($scope.clusterEntity.clusterModel.cluster.properties.property.length === 0) {
delete $scope.clusterEntity.clusterModel.cluster.properties;
}
}
var lastLocationIndex = $scope.clusterEntity.clusterModel.cluster.locations.location.length - 1;
if (
$scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._name === "" ||
$scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._name === undefined ||
$scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._path === "" ||
$scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._path === undefined
) {
$scope.removeLocation(lastLocationIndex);
}
//deletes ACL if empty
/*if ($scope.clusterEntity.clusterModel.cluster.ACL &&
$scope.clusterEntity.clusterModel.cluster.ACL._owner === "") {
delete $scope.clusterEntity.clusterModel.cluster.ACL;
}*/
//deletes tags if empty
if (!$scope.clusterEntity.clusterModel.cluster.tags) {
delete $scope.clusterEntity.clusterModel.cluster.tags;
}
//moves properties to be the last element if acl exists
$scope.arrangeFieldsOrder();
}
$scope.arrangeFieldsOrder = function (xmlObj) {
var BK,
orderedObj = {};
if (xmlObj) {
BK = xmlObj.cluster;
} else {
BK = $scope.clusterEntity.clusterModel.cluster;
}
orderedObj._xmlns = 'uri:falcon:cluster:0.1';
orderedObj._name = BK._name;
orderedObj._description = BK._description;
orderedObj._colo = BK._colo;
if (BK.tags) { orderedObj.tags = BK.tags; }
if (BK.interfaces) { orderedObj.interfaces = BK.interfaces; }
if (BK.locations) { orderedObj.locations = BK.locations; }
if (BK.ACL) { orderedObj.ACL = BK.ACL; }
if (BK.properties) { orderedObj.properties = BK.properties; }
delete $scope.clusterEntity.clusterModel.cluster;
$scope.clusterEntity.clusterModel.cluster = orderedObj;
};
//--------------TAGS------------------------//
$scope.convertTags = function () {
var result = [];
if($scope.tagsArray) {
$scope.tagsArray.forEach(function(element) {
if(element.key && element.value) {
result.push(element.key + "=" + element.value);
}
});
}
result = result.join(",");
$scope.clusterEntity.clusterModel.cluster.tags = result;
};
$scope.splitTags = function () {
$scope.tagsArray = [];
if ($scope.clusterEntity.clusterModel.cluster.tags) {
$scope.clusterEntity.clusterModel.cluster.tags.split(",").forEach(function (fieldToSplit) {
var splittedString = fieldToSplit.split("=");
$scope.tagsArray.push({key: splittedString[0], value: splittedString[1]});
});
}
};
$scope.addTag = function () {
$scope.tagsArray.push({key: null, value: null});
};
$scope.removeTag = function (index) {
if (!isNaN(index) && index !== undefined && index !== null) {
$scope.tagsArray.splice(index, 1);
$scope.convertTags();
}
};
$scope.toggleclick = function () {
$('.formBoxContainer').toggleClass('col-xs-14 ');
$('.xmlPreviewContainer ').toggleClass('col-xs-10 hide');
$('.preview').toggleClass('pullOver pullOverXml');
($('.preview').hasClass('pullOver')) ? $('.preview').find('button').html('Preview XML') : $('.preview').find('button').html('Hide XML');
($($("textarea")[0]).attr("ng-model") == "prettyXml" ) ? $($("textarea")[0]).css("min-height", $(".formBoxContainer").height() - 40 ) : '';
};
//-------------------------------------//
//----------LOCATION-------------------//
$scope.addLocation = function () {
var lastOneIndex = $scope.clusterEntity.clusterModel.cluster.locations.location.length - 1;
if (!$scope.clusterEntity.clusterModel.cluster.locations.location[lastOneIndex]._name ||
!$scope.clusterEntity.clusterModel.cluster.locations.location[lastOneIndex]._path) {
//console.log('location empty');
} else {
$scope.clusterEntity.clusterModel.cluster.locations.location.push({_name: "", _path: ""});
}
};
$scope.removeLocation = function (index) {
if(!isNaN(index) && index !== undefined && index !== null) {
$scope.clusterEntity.clusterModel.cluster.locations.location.splice(index, 1);
}
};
//-----------PROPERTIES----------------//
$scope.addProperty = function () {
var lastOne = $scope.clusterEntity.clusterModel.cluster.properties.property.length - 1;
if($scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._name && $scope.clusterEntity.clusterModel.cluster.properties.property[lastOne]._value){
$scope.clusterEntity.clusterModel.cluster.properties.property.push({ _name: "", _value: ""});
// $scope.tempPropModel = { _name: "", _value: ""};
}
};
$scope.removeProperty = function(index) {
if(index !== null && $scope.clusterEntity.clusterModel.cluster.properties.property[index]) {
$scope.clusterEntity.clusterModel.cluster.properties.property.splice(index, 1);
}
};
$scope.isActive = function (route) {
return route === $state.current.name;
};
$scope.isCompleted = function (route) {
return $state.get(route).data && $state.get(route).data.completed;
};
$scope.validateLocations = function(){
var stagingLoc;
var workingLoc;
$scope.clusterEntity.clusterModel.cluster.locations.location.forEach(function(location){
if(location._name == "staging"){
stagingLoc = location._path;
}
if(location._name == "working"){
workingLoc = location._path;
}
});
if(stagingLoc && workingLoc && stagingLoc == workingLoc){
$scope.locationsEqualError = true;
}else{
$scope.locationsEqualError = false;
}
return $scope.locationsEqualError;
};
//--------------------------------------//
$scope.goSummaryStep = function (formInvalid) {
$state.current.data = $state.current.data || {};
$state.current.data.completed = !formInvalid;
SpinnersFlag.show = true;
if($scope.validateLocations()){
SpinnersFlag.show = false;
return;
}
if (!$scope.validations.nameAvailable || formInvalid) {
validationService.displayValidations.show = true;
validationService.displayValidations.nameShow = true;
SpinnersFlag.show = false;
return;
}
cleanModel();
$scope.secondStep = true;
$state.go("forms.cluster.summary");
$timeout(function () {
angular.element('.nextBtn').trigger('focus');
}, 500);
};
$scope.hideMessage = function (){
angular.element('.nameValidationMessage').hide();
};
$scope.goGeneralStep = function () {
SpinnersFlag.backShow = true;
$scope.secondStep = false;
validationService.displayValidations.show = false;
validationService.displayValidations.nameShow = false;
$scope.validations.nameAvailable = true;
if(!$scope.registry.check) {
//recovers previously deleted registry object
if($scope.backupRegistryObject){
$scope.clusterEntity.clusterModel.cluster.interfaces.interface.push($scope.backupRegistryObject);
}
}
if(!$scope.spark.check) {
//recovers previously deleted spark object
if($scope.backupSparkObject){
$scope.clusterEntity.clusterModel.cluster.interfaces.interface.push($scope.backupSparkObject);
}
}
if(!$scope.clusterEntity.clusterModel.cluster.tags) {
$scope.clusterEntity.clusterModel.cluster.tags = "";
}
if(!$scope.clusterEntity.clusterModel.cluster.properties) {
$scope.clusterEntity.clusterModel.cluster.properties = {property : [{ _name: "", _value: ""}]};
}
var lastLocationIndex = $scope.clusterEntity.clusterModel.cluster.locations.location.length - 1;
if($scope.clusterEntity.clusterModel.cluster.locations.location[lastLocationIndex]._name !== "") {
$scope.addLocation();
}
};
$scope.saveCluster = function () {
SpinnersFlag.show = true;
$scope.saveModelBuffer();
Falcon.logRequest();
if($scope.editingMode) {
Falcon.postUpdateEntity($scope.jsonString, "cluster", $scope.clusterEntity.clusterModel.cluster._name)
.success(function (response) {
$scope.skipUndo = true;
Falcon.logResponse('success', response, false);
$state.go('main');
})
.error(function(err) {
SpinnersFlag.show = false;
Falcon.logResponse('error', err, false);
angular.element('body, html').animate({scrollTop: 0}, 300);
});
} else {
Falcon.postSubmitEntity($scope.jsonString, "cluster")
.success(function (response) {
$scope.skipUndo = true;
Falcon.logResponse('success', response, false);
$state.go('main');
})
.error(function(err) {
SpinnersFlag.show = false;
Falcon.logResponse('error', err, false);
angular.element('body, html').animate({scrollTop: 0}, 300);
});
}
};
//--------------------------------------//
//----------XML preview-----------------//
$scope.xmlPreview.editXML = function () {
$scope.xmlPreview.edit = !$scope.xmlPreview.edit;
};
$scope.revertXml = function() {
if($scope.clusterEntity.clusterModel.cluster.tags !== undefined) {
$scope.convertTags();
}
$scope.showInPreview();
$scope.invalidXml = false;
};
$scope.showInPreview = function() {
var xmlStr = X2jsService.json2xml_str(angular.copy($scope.clusterEntity.clusterModel));
$scope.prettyXml = X2jsService.prettifyXml(xmlStr);
$scope.xml = xmlStr;
};
$scope.transformBack = function() {
try {
var xmlObj = X2jsService.xml_str2json($scope.prettyXml);
if (!xmlObj.cluster.ACL || !xmlObj.cluster.ACL._owner || !xmlObj.cluster.ACL._group || !xmlObj.cluster.ACL._permission) {
xmlObj.cluster.ACL = angular.copy(EntityModel.defaultValues.cluster.cluster.ACL);
xmlObj.cluster.ACL._owner = EntityModel.getUserNameFromCookie();
}
$scope.arrangeFieldsOrder(xmlObj);
if($scope.clusterEntity.clusterModel.cluster.properties && $scope.clusterEntity.clusterModel.cluster.properties.property[0] === '') {
$scope.clusterEntity.clusterModel.cluster.properties.property=[];
}
$scope.invalidXml = false;
}
catch(err) {
$scope.invalidXml = true;
console.log('xml malformed');
}
};
$scope.saveModelBuffer = function () {
$scope.jsonString = angular.toJson($scope.clusterEntity.clusterModel);
//goes back to js to have x2js parse it correctly
$scope.jsonString = JSON.parse($scope.jsonString);
$scope.jsonString = X2jsService.json2xml_str($scope.jsonString);
};
function xmlPreviewCallback() {
if(!$scope.xmlPreview.edit) {
if($scope.clusterEntity.clusterModel.cluster.tags !== undefined) { $scope.convertTags(); }
$scope.showInPreview();
}
else {
$scope.splitTags();
$scope.transformBack();
}
}
$scope.$watch('clusterEntity.clusterModel.cluster', xmlPreviewCallback, true);
$scope.$watch('tagsArray', xmlPreviewCallback, true);
$scope.$watch('prettyXml', xmlPreviewCallback, true);
$scope.skipUndo = false;
$scope.$on('$destroy', function () {
var model = angular.copy($scope.clusterEntity.clusterModel.cluster),
defaultModel = angular.toJson(EntityModel.defaultValues.cluster.cluster);
model.interfaces.interface.forEach(function (item, index) {
if (item._type === "registry" && item._endpoint === "" && item._version === "") {
model.interfaces.interface.splice(index, 1);
}
});
model = angular.toJson(model);
if (!$scope.skipUndo && !angular.equals(model, defaultModel)) {
$scope.$parent.cancel('cluster', $rootScope.previousState);
}
});
//------------init------------//
if($state.params && $state.params.action === 'import'){
$scope.prettyXml = FileApi.fileRaw;
$scope.transformBack();
}else{
normalizeModel();
}
if($state.current.name !=="forms.cluster.general"){
$state.go("forms.cluster.general");
}
$scope.capitalize = function(input) {
return input ? input.charAt(0).toUpperCase() + input.slice(1) : "";
};
$scope.upperCase = function(input) {
return input ? input.toUpperCase() : "";
};
}
]);
})();