You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2017/09/22 02:10:29 UTC
[1/7] atlas git commit: ATLAS-2158: good coding practices
Repository: atlas
Updated Branches:
refs/heads/branch-0.8 3aeba233d -> 2d0bc3c62
ATLAS-2158: good coding practices
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/2d0bc3c6
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/2d0bc3c6
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/2d0bc3c6
Branch: refs/heads/branch-0.8
Commit: 2d0bc3c62022ccdd52ff930b60aefe6200f22d71
Parents: 43ab507
Author: Ashutosh Mestry <am...@apache.org>
Authored: Thu Sep 21 14:45:59 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Sep 21 19:10:04 2017 -0700
----------------------------------------------------------------------
.../atlas/repository/impexp/ZipFileResourceTestUtils.java | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/2d0bc3c6/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
index f0dab47..be8c004 100644
--- a/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ZipFileResourceTestUtils.java
@@ -75,6 +75,9 @@ public class ZipFileResourceTestUtils {
File f = new File(filePath);
String s = FileUtils.readFileToString(f);
assertFalse(StringUtils.isEmpty(s), "Model file read correctly!");
+ if(StringUtils.isEmpty(s)) {
+ throw new IOException("Unable to read file: " + fileName);
+ }
return s;
}
@@ -138,9 +141,12 @@ public class ZipFileResourceTestUtils {
}
private static void createTypesAsNeeded(AtlasTypesDef typesFromJson, AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
- AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(typesFromJson, typeRegistry);
+ if(typesFromJson == null) {
+ return;
+ }
- if (!typesToCreate.isEmpty()) {
+ AtlasTypesDef typesToCreate = AtlasTypeDefStoreInitializer.getTypesToCreate(typesFromJson, typeRegistry);
+ if (typesToCreate != null && !typesToCreate.isEmpty()) {
typeDefStore.createTypesDef(typesToCreate);
}
}
[4/7] atlas git commit: ATLAS-2100: UserProfile & SavedSearch API
implementation. Fixed accidentally deleted type.
Posted by ma...@apache.org.
ATLAS-2100: UserProfile & SavedSearch API implementation. Fixed accidentally deleted type.
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/2e138da4
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/2e138da4
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/2e138da4
Branch: refs/heads/branch-0.8
Commit: 2e138da48861f213fb415bf19af026b9821f5022
Parents: 3aeba23
Author: ashutoshm <am...@hortonworks.com>
Authored: Mon Sep 18 16:52:14 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Sep 21 19:10:04 2017 -0700
----------------------------------------------------------------------
addons/models/0010-base_model.json | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/2e138da4/addons/models/0010-base_model.json
----------------------------------------------------------------------
diff --git a/addons/models/0010-base_model.json b/addons/models/0010-base_model.json
index db95d7e..8f38f59 100644
--- a/addons/models/0010-base_model.json
+++ b/addons/models/0010-base_model.json
@@ -1,7 +1,23 @@
{
"enumDefs": [],
"structDefs": [],
- "classificationDefs": [],
+ "classificationDefs": [
+ {
+ "name": "TaxonomyTerm",
+ "superTypes": [],
+ "typeVersion": "1.0",
+ "attributeDefs": [
+ {
+ "name": "atlas.taxonomy",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": false,
+ "isOptional": true,
+ "isUnique": false
+ }
+ ]
+ }
+ ],
"entityDefs": [
{
"name": "Referenceable",
[2/7] atlas git commit: ATLAS-2150: UI to support search-history and
favorites
Posted by ma...@apache.org.
ATLAS-2150: UI to support search-history and favorites
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/d0343f10
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/d0343f10
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/d0343f10
Branch: refs/heads/branch-0.8
Commit: d0343f1048a4cd3de8e9440c1536bef5f82a6273
Parents: 466703f
Author: kevalbhatt <kb...@apache.org>
Authored: Wed Sep 20 23:50:42 2017 +0530
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Sep 21 19:10:04 2017 -0700
----------------------------------------------------------------------
dashboardv2/public/css/scss/loader.scss | 7 +
dashboardv2/public/css/scss/tag.scss | 5 +
dashboardv2/public/css/scss/theme.scss | 18 +-
.../detail_page/DetailPageLayoutView_tmpl.html | 26 +--
.../entity/CreateEntityLayoutView_tmpl.html | 8 +-
.../profile/ProfileColumnLayoutView_tmpl.html | 2 +-
.../templates/search/SaveAsLayoutView_tmpl.html | 24 +++
.../search/SaveSearchItemView_tmpl.html | 28 ++++
.../js/templates/search/SaveSearch_tmpl.html | 29 ++++
.../templates/search/SearchLayoutView_tmpl.html | 8 +-
.../public/js/utils/CommonViewFunction.js | 164 +++++++++++++++++--
dashboardv2/public/js/utils/Enums.js | 11 ++
dashboardv2/public/js/utils/Messages.js | 12 +-
dashboardv2/public/js/utils/Overrides.js | 7 +
dashboardv2/public/js/utils/UrlLinks.js | 10 +-
.../public/js/views/search/QueryBuilderView.js | 4 +-
.../public/js/views/search/SaveAsLayoutView.js | 97 +++++++++++
.../js/views/search/SaveSearchItemView.js | 127 ++++++++++++++
.../public/js/views/search/SaveSearchView.js | 143 ++++++++++++++++
.../public/js/views/search/SearchLayoutView.js | 100 ++++++++++-
20 files changed, 778 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/css/scss/loader.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/loader.scss b/dashboardv2/public/css/scss/loader.scss
index 43f15fd..d323212 100644
--- a/dashboardv2/public/css/scss/loader.scss
+++ b/dashboardv2/public/css/scss/loader.scss
@@ -63,6 +63,13 @@
display: none;
}
+.fontLoader-relative {
+ @extend .fontLoader;
+ position: relative;
+ left: 0%;
+ text-align: center;
+}
+
.initialLoading {
display: block;
position: absolute;
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/css/scss/tag.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/tag.scss b/dashboardv2/public/css/scss/tag.scss
index 6556784..8b5e6e2 100644
--- a/dashboardv2/public/css/scss/tag.scss
+++ b/dashboardv2/public/css/scss/tag.scss
@@ -19,6 +19,10 @@
//tag.scss
.tag-tree {
padding: 0; // overflow: auto;
+ &.saveSearchList {
+ height: 150px;
+ overflow-y: auto;
+ }
>li {
list-style: none;
cursor: pointer;
@@ -52,6 +56,7 @@
display: none;
position: absolute;
right: 0;
+ color: $white;
padding: 5px 10px;
}
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/css/scss/theme.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/theme.scss b/dashboardv2/public/css/scss/theme.scss
index 26e507f..dc56148 100644
--- a/dashboardv2/public/css/scss/theme.scss
+++ b/dashboardv2/public/css/scss/theme.scss
@@ -84,6 +84,10 @@ header {
#sideNav-wrapper {
color: $white;
font-size: 16px !important;
+ .well {
+ background-color: $color_tuna_approx;
+ border: 1px solid #666363;
+ }
}
.page-title {
@@ -272,17 +276,6 @@ hr[size="10"] {
margin-right: 0px !important;
}
-.backButton {
- display: block;
- margin: 0px 13px;
- &:hover {
- color: $color_jungle_green_approx;
- }
- &:active {
- color: $color_jungle_green_approx;
- }
-}
-
.position-relative {
position: relative;
}
@@ -308,7 +301,8 @@ hr[size="10"] {
.add-seperator {
margin-bottom: 10px;
- border-bottom: 1px solid $color_mirage_approx
+ border-bottom: 1px solid $color_mirage_approx;
+ padding-bottom: 10px;
}
.legend-sm {
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
index 21931e5..8acd8e4 100644
--- a/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/detail_page/DetailPageLayoutView_tmpl.html
@@ -20,7 +20,7 @@
</div>
<div class="entityDetail form-horizontal col-md-12">
<div class="row">
- <a href="javascript:void(0);" class="backButton" data-id="backButton"><i class="fa fa-chevron-left"></i> Back To Results</a>
+ <a href="javascript:void(0);" data-id="backButton"><i class="fa fa-chevron-left"></i> Back To Results</a>
</div>
<h1 class="form-group"><span data-id="title"></span></h1> {{#if entityUpdate}}
<div data-id="editButtonContainer" class="pull-right"></div>
@@ -95,43 +95,43 @@
</div>
<div class="tab-content">
<div id="tab-details" role="properties" class="tab-pane active">
- <div id="r_entityDetailTableLayoutView" style="position: relative;">
- <div class="fontLoader">
+ <div id="r_entityDetailTableLayoutView">
+ <div class="fontLoader-relative">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
</div>
<div id="tab-tagTable" role="tags" class="tab-pane fade">
- <div id="r_tagTableLayoutView" style="position: relative;">
- <div class="fontLoader">
+ <div id="r_tagTableLayoutView">
+ <div class="fontLoader-relative">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
</div>
<div id="tab-termTable" role="terms" class="tab-pane">
- <div id="r_termTableLayoutView" style="position: relative;">
- <div class="fontLoader">
+ <div id="r_termTableLayoutView">
+ <div class="fontLoader-relative">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
</div>
<div id="tab-audit" role="audits" class="tab-pane">
- <div id="r_auditTableLayoutView" style="position: relative;">
- <div class="fontLoader">
+ <div id="r_auditTableLayoutView">
+ <div class="fontLoader-relative">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
</div>
<div id="tab-schema" role="schema" class="tab-pane">
- <div id="r_schemaTableLayoutView" style="position: relative;">
- <div class="fontLoader">
+ <div id="r_schemaTableLayoutView">
+ <div class="fontLoader-relative">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
</div>
<div id="tab-profile" role="profile" class="tab-pane">
- <div id="r_profileLayoutView" style="position: relative;">
- <div class="fontLoader">
+ <div id="r_profileLayoutView">
+ <div class="fontLoader-relative">
<i class="fa fa-refresh fa-spin-custom"></i>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html b/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html
index ef99f2d..55f70a1 100644
--- a/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/entity/CreateEntityLayoutView_tmpl.html
@@ -40,8 +40,6 @@
<div class="col-md-12 entityInputData" data-id="entityInputData"></div>
</div>
</form>
-<div class="" style="position: relative;height: 8px;">
- <div class="fontLoader entityLoader" style="display:none">
- <i class="fa fa-refresh fa-spin-custom"></i>
- </div>
-</div>
+<div class="fontLoader-relative entityLoader" style="display:none">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/templates/profile/ProfileColumnLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/profile/ProfileColumnLayoutView_tmpl.html b/dashboardv2/public/js/templates/profile/ProfileColumnLayoutView_tmpl.html
index 5215254..5903afb 100644
--- a/dashboardv2/public/js/templates/profile/ProfileColumnLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/profile/ProfileColumnLayoutView_tmpl.html
@@ -35,7 +35,7 @@
<h4 class="col-md-12">{{typeObject.label}}</h4>
</div>
<div class="row">
- <a href="javascript:void(0);" class="backButton" data-id="backToYear" style="display: none"><i class="fa fa-chevron-left"></i> Back To Year</a>
+ <a href="javascript:void(0);" data-id="backToYear" style="display: none"><i class="fa fa-chevron-left"></i> Back To Year</a>
</div>
</br>
<div class="row">
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/templates/search/SaveAsLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/search/SaveAsLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SaveAsLayoutView_tmpl.html
new file mode 100644
index 0000000..fd87d28
--- /dev/null
+++ b/dashboardv2/public/js/templates/search/SaveAsLayoutView_tmpl.html
@@ -0,0 +1,24 @@
+<!--
+ * 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.
+-->
+<form name="saveAsform" class="form-horizontal" data-id="">
+ <div class="form-group">
+ <label class="control-label col-sm-2 required" for="name">Name</label>
+ <div class="col-sm-10">
+ <input class="form-control" data-id="saveAsName" placeholder="Name(required)" autofocus/>
+ </div>
+ </div>
+</form>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/templates/search/SaveSearchItemView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/search/SaveSearchItemView_tmpl.html b/dashboardv2/public/js/templates/search/SaveSearchItemView_tmpl.html
new file mode 100644
index 0000000..d84a2ef
--- /dev/null
+++ b/dashboardv2/public/js/templates/search/SaveSearchItemView_tmpl.html
@@ -0,0 +1,28 @@
+<!--
+ * 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.
+-->
+<!-- <div class="row">
+ <div class="col-md-10"><span>{{name}}</span></div>
+ <div class="col-md-2">
+ <button type="button" class="btn btn-danger btn-sm closeInput" data-id="close"><i class="fa fa-times"></i></button>
+ </div>
+</div> -->
+<div data-id="{{guid}}" class="item">
+ <div class="tools">
+ <i class="fa fa-ellipsis-h tagPopover" data-original-title="" title="" data-id=""></i>
+ </div>
+ <a href="javascript:void(0)">{{name}}</a>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/templates/search/SaveSearch_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/search/SaveSearch_tmpl.html b/dashboardv2/public/js/templates/search/SaveSearch_tmpl.html
new file mode 100644
index 0000000..0b20eb4
--- /dev/null
+++ b/dashboardv2/public/js/templates/search/SaveSearch_tmpl.html
@@ -0,0 +1,29 @@
+<!--
+ * 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.
+-->
+<div class="inline-content add-seperator">
+ <div class="inline">
+ <h4>Favorite Search</h4></div>
+ <div class="pull-right">
+ <button type="button" class="btn btn-action btn-sm" disabled="disabled" data-id="saveBtn">Save</button>
+ <button type="button" class="btn btn-action btn-sm" data-id="saveAsBtn">Save As</button>
+ </div>
+</div>
+<ul data-id="itemViewContent" class="tag-tree saveSearchList gray-text">
+ <div class="fontLoader-relative" style="display: block;">
+ <i class="fa fa-refresh fa-spin-custom"></i>
+ </div>
+</ul>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
index cca5f27..9aa6e8d 100644
--- a/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/search/SearchLayoutView_tmpl.html
@@ -31,7 +31,7 @@
</div>
</div>
</div>
- <div class="col-sm-12">
+ <div class="col-sm-12 form-group">
<div class="form-group">
<div class="srchType clearfix">
<span class="srchTitle">Search By Type</span>
@@ -64,4 +64,10 @@
<button type="button" class="btn btn-atlas pull-right" data-id="searchBtn" disabled="disabled">Search</button>
</div>
<div id="searchResult"></div>
+ <div class="col-md-12">
+ <div class="col-md-12 well basicSaveSearch" data-id="r_saveSearchBasic"></div>
+ </div>
+ <div class="col-md-12">
+ <div class="col-md-12 well advanceSaveSearch" data-id="r_saveSearchAdvance" style="display: none"></div>
+ </div>
</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/utils/CommonViewFunction.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/CommonViewFunction.js b/dashboardv2/public/js/utils/CommonViewFunction.js
index dd7e360..0fa8506 100644
--- a/dashboardv2/public/js/utils/CommonViewFunction.js
+++ b/dashboardv2/public/js/utils/CommonViewFunction.js
@@ -16,7 +16,7 @@
* limitations under the License.
*/
-define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enums'], function(require, Utils, Modal, Messages, Enums) {
+define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enums', 'moment'], function(require, Utils, Modal, Messages, Enums, moment) {
'use strict';
var CommonViewFunction = {};
@@ -436,12 +436,110 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
});
})
}
+ CommonViewFunction.generateObjectForSaveSearchApi = function(options) {
+ var obj = {
+ name: options.name,
+ searchParameters: {
+ excludeDeletedEntities: true
+ }
+ };
+ var value = options.value;
+ if (value) {
+ _.each(Enums.extractFromUrlForSearch, function(v, k) {
+ var val = value[k];
+ if (!_.isUndefinedNull(val)) {
+ if (k == "attributes") {
+ val = val.split(',');
+ } else if (k == "tagFilters") {
+ val = CommonViewFunction.attributeFilter.generateAPIObj(val);
+ } else if (k == "entityFilters") {
+ val = CommonViewFunction.attributeFilter.generateAPIObj(val);
+ } else if (k == "includeDE") {
+ if (val) {
+ val = false;
+ } else {
+ val = true;
+ }
+ }
+ }
+ obj.searchParameters[v] = val;
+ });
+ return obj;
+ }
+ }
+ CommonViewFunction.generateUrlFromSaveSearchObject = function(options) {
+ var value = options.value,
+ classificationDefCollection = options.classificationDefCollection,
+ entityDefCollection = options.entityDefCollection,
+ obj = {};
+ if (value) {
+ _.each(Enums.extractFromUrlForSearch, function(v, k) {
+ var val = value[v];
+ if (!_.isUndefinedNull(val)) {
+ if (k == "attributes") {
+ val = val.join(',');
+ } else if (k == "tagFilters") {
+ if (classificationDefCollection) {
+ var classificationDef = classificationDefCollection.fullCollection.findWhere({ 'name': value.classification })
+ attributeDefs = Utils.getNestedSuperTypeObj({
+ collection: classificationDefCollection,
+ attrMerge: true,
+ data: classificationDef.toJSON()
+ });
+ _.each(val.criterion, function(obj) {
+ var attributeDef = _.findWhere(attributeDefs, { 'name': obj.attributeName });
+ if (attributeDef) {
+ if (attributeDef.typeName == "date") {
+ obj.attributeValue = moment(parseInt(obj.attributeValue)).format('MM/DD/YYYY h:mm A');
+ }
+ obj['attributeType'] = attributeDef.typeName;
+ }
+ });
+ }
+ val = CommonViewFunction.attributeFilter.generateUrl(val.criterion);
+ } else if (k == "entityFilters") {
+ if (entityDefCollection) {
+ var entityDef = entityDefCollection.fullCollection.findWhere({ 'name': value.typeName }),
+ attributeDefs = Utils.getNestedSuperTypeObj({
+ collection: entityDefCollection,
+ attrMerge: true,
+ data: entityDef.toJSON()
+ });
+ _.each(val.criterion, function(obj) {
+ var attributeDef = _.findWhere(attributeDefs, { 'name': obj.attributeName });
+ if (attributeDef) {
+ if (attributeDef.typeName == "date") {
+ obj.attributeValue = moment(parseInt(obj.attributeValue)).format('MM/DD/YYYY h:mm A');
+ }
+ obj['attributeType'] = attributeDef.typeName;
+ }
+ });
+ }
+ val = CommonViewFunction.attributeFilter.generateUrl(val.criterion);
+ } else if (k == "includeDE") {
+ if (val) {
+ val = false;
+ } else {
+ val = true;
+ }
+ }
+ }
+ obj[k] = val;
+ });
+ return obj;
+ }
+ }
CommonViewFunction.attributeFilter = {
generateUrl: function(attrObj) {
var attrQuery = [];
if (attrObj) {
_.each(attrObj, function(obj) {
- attrQuery.push(obj.id + "::" + obj.operator + "::" + obj.value + "::" + obj.type);
+ var url = [(obj.id || obj.attributeName), mapApiOperatorToUI(obj.operator), (obj.value || obj.attributeValue)],
+ type = (obj.type || obj.attributeType);
+ if (type) {
+ url.push(type);
+ }
+ attrQuery.push(url.join("::"));
});
if (attrQuery.length) {
return attrQuery.join();
@@ -451,13 +549,40 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
} else {
return null;
}
+
+ function mapApiOperatorToUI(oper) {
+ if (oper == "eq") {
+ return "=";
+ } else if (oper == "neq") {
+ return "!=";
+ } else if (oper == "lt") {
+ return "<";
+ } else if (oper == "lte") {
+ return "<=";
+ } else if (oper == "gt") {
+ return ">";
+ } else if (oper == "gte") {
+ return ">=";
+ } else if (oper == "startsWith") {
+ return "begins_with";
+ } else if (oper == "endsWith") {
+ return "ends_with";
+ } else if (oper == "contains") {
+ return "contains";
+ }
+ return oper;
+ }
},
extractUrl: function(urlObj) {
var attrObj = [];
if (urlObj && urlObj.length) {
_.each(urlObj.split(","), function(obj) {
var temp = obj.split("::");
- attrObj.push({ id: temp[0], operator: temp[1], value: temp[2], type: temp[3] });
+ var finalObj = { id: temp[0], operator: temp[1], value: temp[2] }
+ if (temp[3]) {
+ finalObj['type'] = temp[3];
+ }
+ attrObj.push(finalObj);
});
return attrObj;
} else {
@@ -479,23 +604,38 @@ define(['require', 'utils/Utils', 'modules/Modal', 'utils/Messages', 'utils/Enum
var convertObj = [];
_.each(rules, function(rulObj) {
var tempObj = {};
- // For nested
- // if (rulObj.rules) {
- // tempObj = {
- // "condition": "AND",
- // "criterion": convertKeyAndExtractObj(rulObj.rules)
- // }
- // } else {
- // }
tempObj = {
"attributeName": rulObj.id,
- "operator": rulObj.operator,
+ "operator": mapUiOperatorToAPI(rulObj.operator),
"attributeValue": (rulObj.type === "date" ? Date.parse(rulObj.value) : rulObj.value)
}
convertObj.push(tempObj);
});
return convertObj;
}
+
+ function mapUiOperatorToAPI(oper) {
+ if (oper == "=") {
+ return "eq";
+ } else if (oper == "!=") {
+ return "neq";
+ } else if (oper == "<") {
+ return "lt";
+ } else if (oper == "<=") {
+ return "lte";
+ } else if (oper == ">") {
+ return "gt";
+ } else if (oper == ">=") {
+ return "gte";
+ } else if (oper == "begins_with") {
+ return "startsWith";
+ } else if (oper == "ends_with") {
+ return "endsWith";
+ } else if (oper == "contains") {
+ return "contains";
+ }
+ return oper;
+ }
}
}
CommonViewFunction.addRestCsrfCustomHeader = function(xhr, settings) {
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/utils/Enums.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/Enums.js b/dashboardv2/public/js/utils/Enums.js
index db2c46c..78445e1 100644
--- a/dashboardv2/public/js/utils/Enums.js
+++ b/dashboardv2/public/js/utils/Enums.js
@@ -56,6 +56,17 @@ define(['require'], function(require) {
'decile-frequency': "Decile Frequency Distribution",
'annual': "Annual Distribution"
}
+ Enums.extractFromUrlForSearch = {
+ "pageLimit": "limit",
+ "type": "typeName",
+ "tag": "classification",
+ "query": "query",
+ "pageOffset": "offset",
+ "includeDE": "excludeDeletedEntities",
+ "tagFilters": "tagFilters",
+ "entityFilters": "entityFilters",
+ "attributes": "attributes"
+ }
return Enums;
});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/utils/Messages.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/Messages.js b/dashboardv2/public/js/utils/Messages.js
index b91f940..feccdc0 100644
--- a/dashboardv2/public/js/utils/Messages.js
+++ b/dashboardv2/public/js/utils/Messages.js
@@ -33,14 +33,22 @@ define(['require'], function(require) {
removeErrorMessage: " could not be removed",
editSuccessMessage: " has been updated successfully",
assignDeletedEntity: " is deleted, tag cannot be assigned",
+ conformation: {
+ deleteMessage: "Are you sure you want to delete "
+ },
search: {
noRecordForPage: "No record found at ",
- onSamePage : "You are on the same page!"
+ onSamePage: "You are on the same page!",
+ favoriteSearch: {
+ save: "Do you want to overwrite ",
+ notSelectedFavoriteElement: "Please select any one favorite search",
+ notSelectedSearchFilter:"Please select at least one filter"
+ }
},
tag: {
addAttributeSuccessMessage: "Tag attribute is added successfully",
updateTagDescriptionMessage: "Tag description is updated successfully",
- updateTermDescriptionMessage: "Term description is updated successfully",
+ updateTermDescriptionMessage: "Term description is updated successfully"
}
};
return Messages;
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/utils/Overrides.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/Overrides.js b/dashboardv2/public/js/utils/Overrides.js
index 0be9a83..bdc15db 100644
--- a/dashboardv2/public/js/utils/Overrides.js
+++ b/dashboardv2/public/js/utils/Overrides.js
@@ -47,6 +47,13 @@ define(['require', 'utils/Utils', 'marionette', 'backgrid', 'asBreadcrumbs', 'jq
} else {
return false;
}
+ },
+ isUndefinedNull: function(val) {
+ if (_.isUndefined(val) || _.isNull(val)) {
+ return true
+ } else {
+ return false;
+ }
}
});
var getPopoverEl = function(e) {
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/utils/UrlLinks.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index df20cf1..913df24 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -107,6 +107,14 @@ define(['require', 'utils/Enums'], function(require, Enums) {
return searchUrl;
}
},
+ saveSearchApiUrl: function(saveSearchType) {
+ var saveSearchUrl = this.searchApiUrl() + "/saved";
+ if (saveSearchType) {
+ return saveSearchUrl + '/' + saveSearchType;
+ } else {
+ return saveSearchUrl;
+ }
+ },
versionApiUrl: function() {
return this.baseUrl + '/admin/version';
},
@@ -117,4 +125,4 @@ define(['require', 'utils/Enums'], function(require, Enums) {
};
return UrlLinks;
-});
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/views/search/QueryBuilderView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/search/QueryBuilderView.js b/dashboardv2/public/js/views/search/QueryBuilderView.js
index e94c05d..a6a1e3a 100644
--- a/dashboardv2/public/js/views/search/QueryBuilderView.js
+++ b/dashboardv2/public/js/views/search/QueryBuilderView.js
@@ -153,8 +153,8 @@ define(['require',
allow_groups: false,
allow_empty: true,
operators: [
- { type: '=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
- { type: '!=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
+ { type: '=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
+ { type: '!=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean', 'enum'] },
{ type: '>', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
{ type: '<', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
{ type: '>=', nb_inputs: 1, multiple: false, apply_to: ['number', 'string', 'boolean'] },
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/views/search/SaveAsLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/search/SaveAsLayoutView.js b/dashboardv2/public/js/views/search/SaveAsLayoutView.js
new file mode 100644
index 0000000..f4f4c68
--- /dev/null
+++ b/dashboardv2/public/js/views/search/SaveAsLayoutView.js
@@ -0,0 +1,97 @@
+/**
+ * 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.
+ */
+
+define(['require',
+ 'backbone',
+ 'hbs!tmpl/search/SaveAsLayoutView_tmpl',
+ 'utils/Utils',
+ 'modules/Modal',
+ 'utils/UrlLinks',
+ 'platform',
+ 'models/VSearch',
+ 'utils/CommonViewFunction',
+ 'utils/Messages'
+], function(require, Backbone, SaveAsLayoutViewTmpl, Utils, Modal, UrlLinks, platform, VSearch, CommonViewFunction, Messages) {
+
+
+ var SaveAsLayoutView = Backbone.Marionette.LayoutView.extend({
+ _viewName: 'SaveAsLayoutView',
+ template: SaveAsLayoutViewTmpl,
+ regions: {},
+ ui: {
+ saveAsName: "[data-id='saveAsName']"
+ },
+ events: function() {
+ var events = {};
+ return events;
+ },
+ initialize: function(options) {
+ var that = this;
+ _.extend(this, _.pick(options, 'value', 'collection', 'searchVent', 'typeHeaders', 'fetchFavioriteCollection', 'getValue', 'isBasic'));
+
+ this.model = new VSearch();
+ var modal = new Modal({
+ title: 'Enter your search name',
+ content: this,
+ cancelText: "Cancel",
+ okCloses: false,
+ okText: 'Create',
+ allowCancel: true
+ }).open();
+ modal.$el.find('button.ok').attr("disabled", "true");
+ this.ui.saveAsName.on('keyup', function(e) {
+ modal.$el.find('button.ok').removeAttr("disabled");
+ });
+ this.ui.saveAsName.on('keyup', function(e) {
+ if ((e.keyCode == 8 || e.keyCode == 32 || e.keyCode == 46) && e.currentTarget.value.trim() == "") {
+ modal.$el.find('button.ok').attr("disabled", "true");
+ }
+ });
+ modal.on('ok', function() {
+ modal.$el.find('button.ok').attr("disabled", "true");
+ that.onCreateButton(modal);
+ });
+ modal.on('closeModal', function() {
+ modal.trigger('cancel');
+ });
+ },
+ onCreateButton: function(modal) {
+ var that = this,
+ obj = { value: this.getValue(), name: this.ui.saveAsName.val() },
+ saveObj = CommonViewFunction.generateObjectForSaveSearchApi(obj);
+ if (this.isBasic) {
+ saveObj['searchType'] = "BASIC";
+ } else {
+ saveObj['searchType'] = "ADVANCED";
+ }
+ that.model.urlRoot = UrlLinks.saveSearchApiUrl();
+ that.model.save(saveObj, {
+ success: function(model, data) {
+ if (that.collection) {
+ that.collection.add(data);
+ }
+ Utils.notifySuccess({
+ content: obj.name + Messages.addSuccessMessage
+ });
+ }
+ });
+ modal.trigger('cancel');
+ }
+ });
+ return SaveAsLayoutView;
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/views/search/SaveSearchItemView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/search/SaveSearchItemView.js b/dashboardv2/public/js/views/search/SaveSearchItemView.js
new file mode 100644
index 0000000..46704a9
--- /dev/null
+++ b/dashboardv2/public/js/views/search/SaveSearchItemView.js
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+define(['require',
+ 'backbone',
+ 'hbs!tmpl/search/SaveSearchItemView_tmpl',
+ 'utils/UrlLinks',
+ 'utils/Utils',
+ 'utils/CommonViewFunction',
+ 'utils/Messages'
+], function(require, Backbone, SaveSearchItemView_tmpl, UrlLinks, Utils, CommonViewFunction, Messages) {
+ 'use strict';
+ return Backbone.Marionette.ItemView.extend({
+ template: SaveSearchItemView_tmpl,
+ tagName: 'li',
+ className: 'parent-node',
+ ui: {
+ stateChange: '.item',
+ tools: '.tools'
+ },
+ events: function() {
+ var events = {};
+ events['click ' + this.ui.stateChange] = 'stateChange';
+ events['click ' + this.ui.tools] = function(e) {
+ e.stopPropagation();
+ };
+ return events;
+ },
+ initialize: function(options) {
+ _.extend(this, _.pick(options, 'collection', 'typeHeaders', 'applyValue', 'fetchFavioriteCollection', 'isBasic', 'classificationDefCollection', 'entityDefCollection'));
+ this.model.id = this.model.get('guid');
+ this.model.idAttribute = 'guid';
+ this.searchTypeObj = {
+ 'searchType': 'dsl',
+ 'dslChecked': 'true'
+ }
+ if (this.isBasic) {
+ this.searchTypeObj.dslChecked = false;
+ this.searchTypeObj.searchType = 'basic';
+ }
+ },
+ onRender: function() {
+ this.showToolTip();
+ },
+ stateChange: function() {
+ this.applyValue(this.model, this.searchTypeObj);
+ this.trigger('item:clicked');
+ this.ui.stateChange.parent('li').addClass('active').siblings().removeClass('active');
+ },
+ showToolTip: function(e) {
+ var that = this;
+ Utils.generatePopover({
+ el: this.$('.tagPopover'),
+ container: this.$el,
+ popoverOptions: {
+ content: function() {
+ return "<ul class='saveSearchPopoverList'>" +
+ "<li class='th' ><i class='fa fa-search'></i> <a href='javascript:void(0)' data-fn='onSearch'>Search </a></li>" +
+ "<li class='listTerm' ><i class='fa fa-trash-o'></i> <a href='javascript:void(0)' data-fn='onDelete'>Delete</a></li>" +
+ "</ul>";
+ }
+ }
+ }).parent('div.tools').on('click', 'li', function(e) {
+ e.stopPropagation();
+ that.$('.tagPopover').popover('hide');
+ that[$(this).find('a').data('fn')](e)
+ });
+ },
+ onSearch: function() {
+ var searchParameters = this.model.toJSON().searchParameters,
+ params = CommonViewFunction.generateUrlFromSaveSearchObject({
+ value: searchParameters,
+ classificationDefCollection: this.classificationDefCollection,
+ entityDefCollection: this.entityDefCollection
+ });
+ Utils.setUrl({
+ url: '#!/search/searchResult',
+ urlParams: _.extend(params, this.searchTypeObj),
+ mergeBrowserUrl: false,
+ trigger: true,
+ updateTabState: true
+ });
+ },
+ onDelete: function() {
+ var that = this;
+ var notifyObj = {
+ modal: true,
+ html: true,
+ text: Messages.conformation.deleteMessage + "<b>" + this.model.get('name') + "</b>" + " ?",
+ ok: function(argument) {
+ that.onDeleteNotifyOk();
+ },
+ cancel: function(argument) {}
+ }
+ Utils.notifyConfirm(notifyObj);
+ },
+ onDeleteNotifyOk: function() {
+ var that = this;
+ this.model.urlRoot = UrlLinks.saveSearchApiUrl();
+ this.model.destroy({
+ wait: true,
+ success: function(model, data) {
+ if (that.collection) {
+ that.collection.remove(data);
+ }
+ Utils.notifySuccess({
+ content: that.model.get('name') + Messages.deleteSuccessMessage
+ });
+ }
+ });
+ }
+ });
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/views/search/SaveSearchView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/search/SaveSearchView.js b/dashboardv2/public/js/views/search/SaveSearchView.js
new file mode 100644
index 0000000..aed8714
--- /dev/null
+++ b/dashboardv2/public/js/views/search/SaveSearchView.js
@@ -0,0 +1,143 @@
+/**
+ * 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.
+ */
+
+define(['require',
+ 'backbone',
+ 'hbs!tmpl/search/SaveSearch_tmpl',
+ 'views/search/SaveSearchItemView',
+ 'collection/VSearchList',
+ 'utils/Utils',
+ 'utils/UrlLinks',
+ 'utils/CommonViewFunction',
+ 'utils/Messages'
+], function(require, Backbone, SaveSearch_Tmpl, SaveSearchItemView, VSearchList, Utils, UrlLinks, CommonViewFunction, Messages) {
+ 'use strict';
+
+ return Backbone.Marionette.CompositeView.extend({
+ template: SaveSearch_Tmpl,
+ childView: SaveSearchItemView,
+ childViewContainer: "[data-id='itemViewContent']",
+ ui: {
+ saveAs: "[data-id='saveAsBtn']",
+ save: "[data-id='saveBtn']"
+ },
+ childViewOptions: function() {
+ return {
+ collection: this.collection,
+ typeHeaders: this.typeHeaders,
+ applyValue: this.applyValue,
+ isBasic: this.isBasic,
+ classificationDefCollection: this.classificationDefCollection,
+ entityDefCollection: this.entityDefCollection,
+ fetchFavioriteCollection: this.fetchCollection.bind(this)
+ };
+ },
+ childEvents: function() {
+ return {
+ "item:clicked": function() {
+ this.ui.save.attr('disabled', false);
+ }
+ }
+ },
+ events: function() {
+ var events = {};
+ events['click ' + this.ui.saveAs] = "saveAs";
+ events['click ' + this.ui.save] = "save";
+ return events;
+ },
+ initialize: function(options) {
+ var that = this;
+ _.extend(this, _.pick(options, 'collection', 'value', 'searchVent', 'typeHeaders', 'applyValue', 'getValue', 'isBasic', 'fetchCollection', 'classificationDefCollection', 'entityDefCollection'));
+ },
+ onRender: function() {
+ this.bindEvents();
+ },
+ bindEvents: function() {
+ this.listenTo(this.collection, "reset error", function(model, response) {
+ this.$('.fontLoader-relative').hide();
+ if (model && model.length) {
+ this.$("[data-id='itemViewContent']").text("");
+ } else {
+ this.$("[data-id='itemViewContent']").text("You don't have any favorite search.")
+ }
+ }, this);
+ },
+ saveAs: function(e) {
+ var that = this,
+ value = this.getValue();
+ if (value && (value.type || value.tag || value.query)) {
+ require([
+ 'views/search/SaveAsLayoutView'
+ ], function(SaveAsLayoutView) {
+ new SaveAsLayoutView({ 'value': that.value, 'searchVent': that.searchVent, 'collection': that.collection, 'getValue': that.getValue, 'isBasic': that.isBasic });
+ });
+ } else {
+ Utils.notifyInfo({
+ content: Messages.search.favoriteSearch.notSelectedSearchFilter
+ })
+ }
+ },
+ save: function() {
+ var that = this,
+ obj = {},
+ notifyObj = {
+ modal: true,
+ html: true,
+ ok: function(argument) {
+ that.onSaveNotifyOk(obj);
+ },
+ cancel: function(argument) {}
+ },
+ selectedEl = this.$('.saveSearchList li.active').find('div.item');
+ obj.name = selectedEl.find('a').text();
+ obj.id = selectedEl.data('id');
+ if (selectedEl && selectedEl.length) {
+ notifyObj['text'] = Messages.search.favoriteSearch.save + " <b>" + obj.name + "</b> ?";
+ Utils.notifyConfirm(notifyObj);
+ } else {
+ Utils.notifyInfo({
+ content: Messages.search.favoriteSearch.notSelectedElement
+ })
+ }
+ },
+ onSaveNotifyOk: function(obj) {
+ var that = this
+ if (obj && obj.id) {
+ var model = new this.collection.model();
+ obj.value = this.getValue();
+ var saveObj = CommonViewFunction.generateObjectForSaveSearchApi(obj);
+ saveObj['guid'] = obj.id;
+ model.urlRoot = UrlLinks.saveSearchApiUrl();
+ model.save(saveObj, {
+ type: 'PUT',
+ success: function(model, data) {
+ if (that.collection) {
+ var collectionRef = that.collection.find({ guid: data.guid });
+ if (collectionRef) {
+ collectionRef.set(data);
+ }
+ }
+ Utils.notifySuccess({
+ content: obj.name + Messages.editSuccessMessage
+ });
+ }
+ });
+ }
+ }
+ });
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/atlas/blob/d0343f10/dashboardv2/public/js/views/search/SearchLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/search/SearchLayoutView.js b/dashboardv2/public/js/views/search/SearchLayoutView.js
index 602ecf8..6b839cd 100644
--- a/dashboardv2/public/js/views/search/SearchLayoutView.js
+++ b/dashboardv2/public/js/views/search/SearchLayoutView.js
@@ -22,8 +22,9 @@ define(['require',
'utils/Utils',
'utils/UrlLinks',
'utils/Globals',
+ 'collection/VSearchList',
'utils/CommonViewFunction'
-], function(require, Backbone, SearchLayoutViewTmpl, Utils, UrlLinks, Globals, CommonViewFunction) {
+], function(require, Backbone, SearchLayoutViewTmpl, Utils, UrlLinks, Globals, VSearchList, CommonViewFunction) {
'use strict';
var SearchLayoutView = Backbone.Marionette.LayoutView.extend(
@@ -34,7 +35,10 @@ define(['require',
template: SearchLayoutViewTmpl,
/** Layout sub regions */
- regions: {},
+ regions: {
+ RSaveSearchBasic: "[data-id='r_saveSearchBasic']",
+ RSaveSearchAdvance: "[data-id='r_saveSearchAdvance']"
+ },
/** ui selector cache */
ui: {
@@ -56,6 +60,8 @@ define(['require',
that = this;
events["keyup " + this.ui.searchInput] = function(e) {
var code = e.which;
+ this.value.query = e.currentTarget.value;
+ this.query[this.type].query = this.value.query;
if (code == 13) {
that.findSearchResult();
}
@@ -111,6 +117,69 @@ define(['require',
}
this.bindEvents();
},
+ renderSaveSearch: function() {
+ var that = this;
+ require(['views/search/SaveSearchView'], function(SaveSearchView) {
+ var saveSearchBaiscCollection = new VSearchList(),
+ saveSearchAdvanceCollection = new VSearchList(),
+ saveSearchCollection = new VSearchList();
+ saveSearchCollection.url = UrlLinks.saveSearchApiUrl();
+ var obj = {
+ value: that.value,
+ searchVent: that.searchVent,
+ typeHeaders: that.typeHeaders,
+ fetchCollection: fetchSaveSearchCollection,
+ classificationDefCollection: that.classificationDefCollection,
+ entityDefCollection: that.entityDefCollection,
+ getValue: function() {
+ var queryObj = that.query[that.type],
+ entityObj = that.searchTableFilters['entityFilters'],
+ tagObj = that.searchTableFilters['tagFilters'],
+ urlObj = Utils.getUrlState.getQueryParams();
+ if (urlObj) {
+ if (urlObj.includeDE == "true") {
+ urlObj.includeDE = true;
+ } else {
+ urlObj.includeDE = false;
+ }
+ }
+ return _.extend({}, queryObj, urlObj, {
+ 'entityFilters': entityObj ? entityObj[queryObj.type] : null,
+ 'tagFilters': tagObj ? tagObj[queryObj.tag] : null,
+ 'type': queryObj.type,
+ 'query': queryObj.query,
+ 'tag': queryObj.tag
+ })
+ },
+ applyValue: function(model, searchType) {
+ that.manualRender(_.extend(searchType, CommonViewFunction.generateUrlFromSaveSearchObject({
+ value: model.get('searchParameters'),
+ classificationDefCollection: that.classificationDefCollection,
+ entityDefCollection: that.entityDefCollection
+ })));
+ }
+ }
+ that.RSaveSearchBasic.show(new SaveSearchView(_.extend(obj, {
+ isBasic: true,
+ collection: saveSearchBaiscCollection
+ })));
+ that.RSaveSearchAdvance.show(new SaveSearchView(_.extend(obj, {
+ isBasic: false,
+ collection: saveSearchAdvanceCollection
+ })));
+
+ function fetchSaveSearchCollection() {
+ saveSearchCollection.fetch({
+ success: function(collection, data) {
+ saveSearchAdvanceCollection.reset(_.where(data, { "searchType": "ADVANCED" }));
+ saveSearchBaiscCollection.reset(_.where(data, { "searchType": "BASIC" }));
+ },
+ silent: true
+ });
+ }
+ fetchSaveSearchCollection();
+ });
+ },
bindEvents: function(param) {
this.listenTo(this.typeHeaders, "reset", function(value) {
this.renderTypeTagList();
@@ -189,12 +258,26 @@ define(['require',
_.extend(this.value, temp);
// on change of type/tag change the offset.
this.query[this.type].pageOffset = 0;
+ _.extend(this.query[this.type], temp);
} else {
// Initial loading handle.
var filterObj = this.searchTableFilters[filterType];
if (filterObj && this.value[key]) {
this.searchTableFilters[filterType][this.value[key]] = this.value[filterType] ? this.value[filterType] : null;
}
+ if (this.value.type) {
+ if (this.value.attributes) {
+ var attributes = _.sortBy(this.value.attributes.split(',')),
+ tableColumn = this.searchTableColumns[this.value.type];
+ if (_.isEmpty(this.searchTableColumns) || !tableColumn) {
+ this.searchTableColumns[this.value.type] = attributes
+ } else if (tableColumn.join(",") !== attributes.join(",")) {
+ this.searchTableColumns[this.value.type] = attributes;
+ }
+ } else if (this.searchTableColumns[this.value.type]) {
+ this.searchTableColumns[this.value.type] = undefined;
+ }
+ }
}
this.makeFilterButtonActive(filterType);
} else {
@@ -229,6 +312,7 @@ define(['require',
placeholder: "Select",
allowClear: true
});
+ this.renderSaveSearch();
},
updateQueryObject: function(param) {
if (param && param.searchType) {
@@ -427,7 +511,7 @@ define(['require',
this.query[this.type].pageLimit = this.value.pageLimit;
}
if (this.value.pageOffset) {
- if (this.query[this.type].query != value) {
+ if (this.query[this.type].query && this.query[this.type].query != value) {
this.query[this.type].pageOffset = 0;
} else {
this.query[this.type].pageOffset = this.value.pageOffset;
@@ -455,11 +539,15 @@ define(['require',
this.$('.temFilterBtn').hide();
this.$('.temFilter').addClass('col-sm-12');
this.$('.temFilter').removeClass('col-sm-10');
+ this.$('.basicSaveSearch').hide();
+ this.$('.advanceSaveSearch').show();
} else {
this.$('.temFilter').addClass('col-sm-10');
this.$('.temFilter').removeClass('col-sm-12');
this.$('.temFilterBtn').show();
this.$('.tagBox').show();
+ this.$('.basicSaveSearch').show();
+ this.$('.advanceSaveSearch').hide();
this.dsl = false;
this.type = "basic";
}
@@ -485,6 +573,12 @@ define(['require',
this.ui.typeLov.val("").trigger("change");
this.ui.tagLov.val("").trigger("change");
this.ui.searchInput.val("");
+ var type = "basicSaveSearch";
+ if (this.type == "dsl") {
+ type = "advanceSaveSearch";
+ }
+ this.$('.' + type + ' .saveSearchList').find('li.active').removeClass('active');
+ this.$('.' + type + ' [data-id="saveBtn"]').attr('disabled', true);
if (!this.dsl) {
this.searchTableFilters.tagFilters = {};
this.searchTableFilters.entityFilters = {};
[6/7] atlas git commit: ATLAS-2157: HiveHook fix to handle getTable()
error for temproray tables
Posted by ma...@apache.org.
ATLAS-2157: HiveHook fix to handle getTable() error for temproray tables
(cherry picked from commit baccd1d8d768cc9e4650c3b39383c304e936e503)
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/43ab507b
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/43ab507b
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/43ab507b
Branch: refs/heads/branch-0.8
Commit: 43ab507b35a1d4c4ee49a7c40ddf1e08a44130ab
Parents: d0343f1
Author: Madhan Neethiraj <ma...@apache.org>
Authored: Wed Sep 20 16:12:23 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Sep 21 19:10:04 2017 -0700
----------------------------------------------------------------------
.../org/apache/atlas/hive/hook/HiveHook.java | 93 +++++++++++++-------
1 file changed, 63 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/43ab507b/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java
----------------------------------------------------------------------
diff --git a/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java b/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java
index 7dc2e2f..aca5645 100755
--- a/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java
+++ b/addons/hive-bridge/src/main/java/org/apache/atlas/hive/hook/HiveHook.java
@@ -526,12 +526,14 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext {
Database db = null;
Table table = null;
Partition partition = null;
- LinkedHashMap<Type, Referenceable> result = new LinkedHashMap<>();
- List<Referenceable> entities = new ArrayList<>();
switch (entity.getType()) {
case DATABASE:
db = entity.getDatabase();
+
+ if (db != null) {
+ db = dgiBridge.hiveClient.getDatabase(db.getName());
+ }
break;
case TABLE:
@@ -549,40 +551,47 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext {
LOG.info("{}: entity-type not handled by Atlas hook. Ignored", entity.getType());
}
- if (db != null) {
- db = dgiBridge.hiveClient.getDatabase(db.getName());
- }
+ Referenceable dbEntity = null;
+ Referenceable tableEntity = null;
if (db != null) {
- Referenceable dbEntity = dgiBridge.createDBInstance(db);
-
- entities.add(dbEntity);
- result.put(Type.DATABASE, dbEntity);
+ dbEntity = dgiBridge.createDBInstance(db);
+ }
- Referenceable tableEntity = null;
+ if (db != null && table != null) {
+ if (existTable != null) {
+ table = existTable;
+ } else {
+ table = refreshTable(dgiBridge, table.getDbName(), table.getTableName());
+ }
if (table != null) {
- if (existTable != null) {
- table = existTable;
- } else {
- table = dgiBridge.hiveClient.getTable(table.getDbName(), table.getTableName());
- }
- //If its an external table, even though the temp table skip flag is on,
- // we create the table since we need the HDFS path to temp table lineage.
- if (skipTempTables &&
- table.isTemporary() &&
- !TableType.EXTERNAL_TABLE.equals(table.getTableType())) {
- LOG.debug("Skipping temporary table registration {} since it is not an external table {} ", table.getTableName(), table.getTableType().name());
-
+ // If its an external table, even though the temp table skip flag is on, we create the table since we need the HDFS path to temp table lineage.
+ if (skipTempTables && table.isTemporary() && !TableType.EXTERNAL_TABLE.equals(table.getTableType())) {
+ LOG.warn("Skipping temporary table registration {} since it is not an external table {} ", table.getTableName(), table.getTableType().name());
} else {
tableEntity = dgiBridge.createTableInstance(dbEntity, table);
- entities.add(tableEntity);
- result.put(Type.TABLE, tableEntity);
}
}
+ }
+
+ LinkedHashMap<Type, Referenceable> result = new LinkedHashMap<>();
+ List<Referenceable> entities = new ArrayList<>();
+
+ if (dbEntity != null) {
+ result.put(Type.DATABASE, dbEntity);
+ entities.add(dbEntity);
+ }
+ if (tableEntity != null) {
+ result.put(Type.TABLE, tableEntity);
+ entities.add(tableEntity);
+ }
+
+ if (!entities.isEmpty()) {
event.addMessage(new HookNotification.EntityUpdateRequest(event.getUser(), entities));
}
+
return result;
}
catch(Exception e) {
@@ -709,7 +718,11 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext {
final String tblQFName = HiveMetaStoreBridge.getTableQualifiedName(dgiBridge.getClusterName(), entity.getTable());
if (!dataSetsProcessed.contains(tblQFName)) {
LinkedHashMap<Type, Referenceable> result = createOrUpdateEntities(dgiBridge, event, entity, false);
- dataSets.put(entity, result.get(Type.TABLE));
+
+ if (result.get(Type.TABLE) != null) {
+ dataSets.put(entity, result.get(Type.TABLE));
+ }
+
dataSetsProcessed.add(tblQFName);
entities.addAll(result.values());
}
@@ -760,7 +773,7 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext {
//Refresh to get the correct location
if(hiveTable != null) {
- hiveTable = dgiBridge.hiveClient.getTable(hiveTable.getDbName(), hiveTable.getTableName());
+ hiveTable = refreshTable(dgiBridge, hiveTable.getDbName(), hiveTable.getTableName());
}
if (hiveTable != null && TableType.EXTERNAL_TABLE.equals(hiveTable.getTableType())) {
@@ -951,12 +964,17 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext {
LOG.debug("Skipping dfs dir input addition to process qualified name {} ", input.getName());
} else if (refs.containsKey(input)) {
if ( input.getType() == Type.PARTITION || input.getType() == Type.TABLE) {
- final Date createTime = HiveMetaStoreBridge.getTableCreatedTime(hiveBridge.hiveClient.getTable(input.getTable().getDbName(), input.getTable().getTableName()));
- addDataset(buffer, refs.get(input), createTime.getTime());
+ Table inputTable = refreshTable(hiveBridge, input.getTable().getDbName(), input.getTable().getTableName());
+
+ if (inputTable != null) {
+ final Date createTime = HiveMetaStoreBridge.getTableCreatedTime(inputTable);
+ addDataset(buffer, refs.get(input), createTime.getTime());
+ }
} else {
addDataset(buffer, refs.get(input));
}
}
+
dataSetsProcessed.add(input.getName().toLowerCase());
}
}
@@ -995,12 +1013,17 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext {
LOG.debug("Skipping dfs dir output addition to process qualified name {} ", output.getName());
} else if (refs.containsKey(output)) {
if ( output.getType() == Type.PARTITION || output.getType() == Type.TABLE) {
- final Date createTime = HiveMetaStoreBridge.getTableCreatedTime(hiveBridge.hiveClient.getTable(output.getTable().getDbName(), output.getTable().getTableName()));
- addDataset(buffer, refs.get(output), createTime.getTime());
+ Table outputTable = refreshTable(hiveBridge, output.getTable().getDbName(), output.getTable().getTableName());
+
+ if (outputTable != null) {
+ final Date createTime = HiveMetaStoreBridge.getTableCreatedTime(outputTable);
+ addDataset(buffer, refs.get(output), createTime.getTime());
+ }
} else {
addDataset(buffer, refs.get(output));
}
}
+
dataSetsProcessed.add(output.getName().toLowerCase());
}
}
@@ -1008,6 +1031,16 @@ public class HiveHook extends AtlasHook implements ExecuteWithHookContext {
}
}
+ private static Table refreshTable(HiveMetaStoreBridge dgiBridge, String dbName, String tableName) {
+ try {
+ return dgiBridge.hiveClient.getTable(dbName, tableName);
+ } catch (HiveException excp) { // this might be the case for temp tables
+ LOG.warn("failed to get details for table {}.{}. Ignoring. {}: {}", dbName, tableName, excp.getClass().getCanonicalName(), excp.getMessage());
+ }
+
+ return null;
+ }
+
private static boolean addQueryType(HiveOperation op, WriteEntity entity) {
if (entity.getWriteType() != null && HiveOperation.QUERY.equals(op)) {
switch (entity.getWriteType()) {
[7/7] atlas git commit: ATLAS-2121: basic-search update to use
case-sensitive filter for type-name / tag-name
Posted by ma...@apache.org.
ATLAS-2121: basic-search update to use case-sensitive filter for type-name / tag-name
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
(cherry picked from commit c0f0abc13037a9d05499dbce2d0e1b65beb9d656)
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/466703fe
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/466703fe
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/466703fe
Branch: refs/heads/branch-0.8
Commit: 466703fe86df3db0f203cbda5847dfbfc160b5af
Parents: 4f1129b
Author: apoorvnaik <ap...@apache.org>
Authored: Tue Sep 19 11:57:01 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Sep 21 19:10:04 2017 -0700
----------------------------------------------------------------------
.../discovery/ClassificationSearchProcessor.java | 10 +++++++++-
.../atlas/discovery/EntitySearchProcessor.java | 17 +++++++++--------
2 files changed, 18 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/466703fe/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java b/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
index 1d4815d..776f5bf 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/ClassificationSearchProcessor.java
@@ -34,6 +34,7 @@ import org.apache.atlas.util.SearchPredicateUtil;
import org.apache.atlas.utils.AtlasPerfTracer;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
+import org.apache.commons.collections.PredicateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -93,7 +94,14 @@ public class ClassificationSearchProcessor extends SearchProcessor {
this.indexQuery = graph.indexQuery(Constants.VERTEX_INDEX, indexQueryString);
- inMemoryPredicate = constructInMemoryPredicate(classificationType, filterCriteria, indexAttributes);
+ Predicate typeNamePredicate = SearchPredicateUtil.getINPredicateGenerator()
+ .generatePredicate(Constants.TYPE_NAME_PROPERTY_KEY, typeAndSubTypes, String.class);
+ Predicate attributePredicate = constructInMemoryPredicate(classificationType, filterCriteria, indexAttributes);
+ if (attributePredicate != null) {
+ inMemoryPredicate = PredicateUtils.andPredicate(typeNamePredicate, attributePredicate);
+ } else {
+ inMemoryPredicate = typeNamePredicate;
+ }
} else {
indexQuery = null;
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/466703fe/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java b/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java
index 970cd28..87efed7 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntitySearchProcessor.java
@@ -80,12 +80,20 @@ public class EntitySearchProcessor extends SearchProcessor {
if (typeSearchByIndex) {
constructTypeTestQuery(indexQuery, typeAndSubTypesQryStr);
+
+ // TypeName check to be done in-memory as well to address ATLAS-2121 (case sensitivity)
+ inMemoryPredicate = typeNamePredicate;
}
if (attrSearchByIndex) {
constructFilterQuery(indexQuery, entityType, filterCriteria, indexAttributes);
- inMemoryPredicate = constructInMemoryPredicate(entityType, filterCriteria, indexAttributes);
+ Predicate attributePredicate = constructInMemoryPredicate(entityType, filterCriteria, indexAttributes);
+ if (inMemoryPredicate != null) {
+ inMemoryPredicate = PredicateUtils.andPredicate(inMemoryPredicate, attributePredicate);
+ } else {
+ inMemoryPredicate = attributePredicate;
+ }
} else {
graphAttributes.addAll(indexAttributes);
}
@@ -110,13 +118,6 @@ public class EntitySearchProcessor extends SearchProcessor {
if (!typeSearchByIndex) {
query.in(Constants.TYPE_NAME_PROPERTY_KEY, typeAndSubTypes);
-
- // Construct a parallel in-memory predicate
- if (graphQueryPredicate != null) {
- graphQueryPredicate = PredicateUtils.andPredicate(graphQueryPredicate, typeNamePredicate);
- } else {
- graphQueryPredicate = typeNamePredicate;
- }
}
// If we need to filter on the trait names then we need to build the query and equivalent in-memory predicate
[5/7] atlas git commit: ATLAS-2148: saved-search API enhancement to
support searchType
Posted by ma...@apache.org.
ATLAS-2148: saved-search API enhancement to support searchType
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/4f1129bd
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/4f1129bd
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/4f1129bd
Branch: refs/heads/branch-0.8
Commit: 4f1129bdb70bb143db7fbc2f09b0f914db3c43d9
Parents: ceb5c0c
Author: ashutoshm <am...@hortonworks.com>
Authored: Tue Sep 19 16:20:52 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Sep 21 19:10:04 2017 -0700
----------------------------------------------------------------------
addons/models/0010-base_model.json | 8 ++
.../model/profile/AtlasUserSavedSearch.java | 35 +++++-
.../atlas/discovery/AtlasDiscoveryService.java | 15 ++-
.../atlas/discovery/EntityDiscoveryService.java | 23 +++-
.../repository/ogm/AtlasSavedSearchDTO.java | 5 +-
.../apache/atlas/repository/ogm/DataAccess.java | 2 +-
.../userprofile/UserProfileService.java | 23 ++--
.../userprofile/UserProfileServiceTest.java | 47 ++++---
.../apache/atlas/web/rest/DiscoveryREST.java | 126 ++++++++++++++-----
9 files changed, 215 insertions(+), 69 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/addons/models/0010-base_model.json
----------------------------------------------------------------------
diff --git a/addons/models/0010-base_model.json b/addons/models/0010-base_model.json
index 8f38f59..0a0244c 100644
--- a/addons/models/0010-base_model.json
+++ b/addons/models/0010-base_model.json
@@ -185,6 +185,14 @@
"isUnique": true
},
{
+ "name": "searchType",
+ "typeName": "string",
+ "cardinality": "SINGLE",
+ "isIndexable": true,
+ "isOptional": false,
+ "isUnique": false
+ },
+ {
"name": "searchParameters",
"typeName": "string",
"cardinality": "SINGLE",
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java b/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java
index b0698fc..8ecd52d 100644
--- a/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java
+++ b/intg/src/main/java/org/apache/atlas/model/profile/AtlasUserSavedSearch.java
@@ -34,26 +34,41 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL
public class AtlasUserSavedSearch extends AtlasBaseModelObject implements Serializable {
private static final long serialVersionUID = 1L;
+ public enum SavedSearchType {
+ BASIC,
+ ADVANCED;
+
+ public static SavedSearchType to(String val) {
+ return SavedSearchType.ADVANCED.name().equalsIgnoreCase(val) ? SavedSearchType.ADVANCED : SavedSearchType.BASIC;
+ }
+ }
+
private String ownerName;
private String name;
+ private SavedSearchType searchType;
private SearchParameters searchParameters;
public AtlasUserSavedSearch() {
- this(null, null, null);
+ this(null, null, SavedSearchType.BASIC, null);
}
- public AtlasUserSavedSearch(String name, SearchParameters searchParameters) {
- this(null, name, searchParameters);
+ public AtlasUserSavedSearch(String name, SavedSearchType searchType, SearchParameters searchParameters) {
+ this(null, name, searchType, searchParameters);
}
public AtlasUserSavedSearch(String ownerName, String name) {
- this(ownerName, name, null);
+ this(ownerName, name, SavedSearchType.BASIC, null);
+ }
+
+ public AtlasUserSavedSearch(String ownerName, String name, SavedSearchType searchType) {
+ this(ownerName, name, searchType, null);
}
- public AtlasUserSavedSearch(String ownerName, String name, SearchParameters searchParameters) {
+ public AtlasUserSavedSearch(String ownerName, String name, SavedSearchType savedSearchType, SearchParameters searchParameters) {
setOwnerName(ownerName);
setName(name);
+ setSearchType(savedSearchType);
setSearchParameters(searchParameters);
}
@@ -74,6 +89,14 @@ public class AtlasUserSavedSearch extends AtlasBaseModelObject implements Serial
this.name = name;
}
+ public SavedSearchType getSearchType() {
+ return searchType;
+ }
+
+ public void setSearchType(SavedSearchType searchType) {
+ this.searchType = searchType;
+ }
+
public SearchParameters getSearchParameters() {
return searchParameters;
}
@@ -82,11 +105,11 @@ public class AtlasUserSavedSearch extends AtlasBaseModelObject implements Serial
this.searchParameters = searchParameters;
}
-
@Override
public StringBuilder toString(StringBuilder sb) {
sb.append(", ownerName=").append(ownerName);
sb.append(", name=").append(name);
+ sb.append(", searchType=").append(searchType);
sb.append(", searchParameters=");
if (searchParameters == null) {
sb.append("null");
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java
index baaee85..630e776 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/AtlasDiscoveryService.java
@@ -24,6 +24,7 @@ import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch.SavedSearchType;
import java.util.List;
@@ -89,14 +90,14 @@ public interface AtlasDiscoveryService {
* @param savedSearch Search to be saved
* @throws AtlasBaseException
*/
- void addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException;
+ AtlasUserSavedSearch addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException;
/**
*
* @param savedSearch Search to be saved
* @throws AtlasBaseException
*/
- void updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException;
+ AtlasUserSavedSearch updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException;
/**
*
@@ -108,12 +109,20 @@ public interface AtlasDiscoveryService {
/**
*
+ * @param guid Guid for the saved search
+ * @return Search object identified by the guid
+ * @throws AtlasBaseException
+ */
+ AtlasUserSavedSearch getSavedSearch(String guid) throws AtlasBaseException;
+
+ /**
+ *
* @param userName Name of the user who the search belongs
* @param searchName Name of the search to be retrieved
* @return Search object identified by the name
* @throws AtlasBaseException
*/
- AtlasUserSavedSearch getSavedSearch(String userName, String searchName) throws AtlasBaseException;
+ AtlasUserSavedSearch getSavedSearch(String userName, String searchName, SavedSearchType searchType) throws AtlasBaseException;
/**
* @param guid Guid for the saved search
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
index ad21ee4..e701dff 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
@@ -33,6 +33,7 @@ import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.instance.AtlasEntityHeader;
import org.apache.atlas.model.instance.AtlasObjectId;
import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch.SavedSearchType;
import org.apache.atlas.query.Expressions.AliasExpression;
import org.apache.atlas.query.Expressions.Expression;
import org.apache.atlas.query.Expressions.SelectExpression;
@@ -804,9 +805,9 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
@Override
- public void addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
+ public AtlasUserSavedSearch addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
try {
- userProfileService.addSavedSearch(savedSearch);
+ return userProfileService.addSavedSearch(savedSearch);
} catch (AtlasBaseException e) {
LOG.error("addSavedSearch({})", savedSearch, e);
throw e;
@@ -815,9 +816,9 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
@Override
- public void updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
+ public AtlasUserSavedSearch updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
try {
- userProfileService.updateSavedSearch(savedSearch);
+ return userProfileService.updateSavedSearch(savedSearch);
} catch (AtlasBaseException e) {
LOG.error("updateSavedSearch({})", savedSearch, e);
throw e;
@@ -835,9 +836,19 @@ public class EntityDiscoveryService implements AtlasDiscoveryService {
}
@Override
- public AtlasUserSavedSearch getSavedSearch(String userName, String searchName) throws AtlasBaseException {
+ public AtlasUserSavedSearch getSavedSearch(String guid) throws AtlasBaseException {
try {
- return userProfileService.getSavedSearch(userName, searchName);
+ return userProfileService.getSavedSearch(guid);
+ } catch (AtlasBaseException e) {
+ LOG.error("getSavedSearch({})", guid, e);
+ throw e;
+ }
+ }
+
+ @Override
+ public AtlasUserSavedSearch getSavedSearch(String userName, String searchName, SavedSearchType searchType) throws AtlasBaseException {
+ try {
+ return userProfileService.getSavedSearch(userName, searchName, searchType);
} catch (AtlasBaseException e) {
LOG.error("getSavedSearch({}, {})", userName, searchName, e);
throw e;
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java b/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java
index 26eee20..aa8fc39 100644
--- a/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java
+++ b/repository/src/main/java/org/apache/atlas/repository/ogm/AtlasSavedSearchDTO.java
@@ -35,6 +35,7 @@ public class AtlasSavedSearchDTO extends AbstractDataTransferObject<AtlasUserSav
private static final String PROPERTY_OWNER_NAME = "ownerName";
private static final String PROPERTY_SEARCH_PARAMETERS = "searchParameters";
private static final String PROPERTY_UNIQUE_NAME = "uniqueName";
+ private static final String PROPERTY_SEARCH_TYPE = "searchType";
public AtlasSavedSearchDTO(AtlasTypeRegistry typeRegistry) {
super(typeRegistry, AtlasUserSavedSearch.class);
@@ -47,6 +48,7 @@ public class AtlasSavedSearchDTO extends AbstractDataTransferObject<AtlasUserSav
savedSearch.setGuid(entity.getGuid());
savedSearch.setName((String) entity.getAttribute(PROPERTY_NAME));
savedSearch.setOwnerName((String) entity.getAttribute(PROPERTY_OWNER_NAME));
+ savedSearch.setSearchType(AtlasUserSavedSearch.SavedSearchType.to((String) entity.getAttribute(PROPERTY_SEARCH_TYPE)));
String jsonSearchParams = (String) entity.getAttribute(PROPERTY_SEARCH_PARAMETERS);
@@ -68,6 +70,7 @@ public class AtlasSavedSearchDTO extends AbstractDataTransferObject<AtlasUserSav
entity.setAttribute(PROPERTY_NAME, obj.getName());
entity.setAttribute(PROPERTY_OWNER_NAME, obj.getOwnerName());
+ entity.setAttribute(PROPERTY_SEARCH_TYPE, obj.getSearchType());
entity.setAttribute(PROPERTY_UNIQUE_NAME, getUniqueValue(obj));
if (obj.getSearchParameters() != null) {
@@ -92,6 +95,6 @@ public class AtlasSavedSearchDTO extends AbstractDataTransferObject<AtlasUserSav
}
private String getUniqueValue(AtlasUserSavedSearch obj) {
- return obj.getOwnerName() + ":" + obj.getName();
+ return String.format("%s:%s:%s", obj.getOwnerName(), obj.getName(), obj.getSearchType()) ;
}
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java b/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java
index bc93cc6..c99d2f8 100644
--- a/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java
+++ b/repository/src/main/java/org/apache/atlas/repository/ogm/DataAccess.java
@@ -51,7 +51,7 @@ public class DataAccess {
throw new AtlasBaseException(AtlasErrorCode.DATA_ACCESS_SAVE_FAILED, obj.toString());
}
- return obj;
+ return this.load(obj);
}
public <T extends AtlasBaseModelObject> T load(T obj) throws AtlasBaseException {
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java b/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java
index 766d1c7..99d13af 100644
--- a/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java
+++ b/repository/src/main/java/org/apache/atlas/repository/userprofile/UserProfileService.java
@@ -22,6 +22,7 @@ import org.apache.atlas.annotation.AtlasService;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.profile.AtlasUserProfile;
import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch.SavedSearchType;
import org.apache.atlas.repository.ogm.DataAccess;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
@@ -41,8 +42,8 @@ public class UserProfileService {
this.dataAccess = dataAccess;
}
- public void saveUserProfile(AtlasUserProfile profile) throws AtlasBaseException {
- dataAccess.save(profile);
+ public AtlasUserProfile saveUserProfile(AtlasUserProfile profile) throws AtlasBaseException {
+ return dataAccess.save(profile);
}
public AtlasUserProfile getUserProfile(String userName) throws AtlasBaseException {
@@ -51,7 +52,7 @@ public class UserProfileService {
return dataAccess.load(profile);
}
- public AtlasUserProfile addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
+ public AtlasUserSavedSearch addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
String userName = savedSearch.getOwnerName();
AtlasUserProfile userProfile = null;
@@ -67,13 +68,21 @@ public class UserProfileService {
checkIfQueryAlreadyExists(savedSearch, userProfile);
userProfile.getSavedSearches().add(savedSearch);
- return dataAccess.save(userProfile);
+ userProfile = dataAccess.save(userProfile);
+ for (AtlasUserSavedSearch s : userProfile.getSavedSearches()) {
+ if(s.getName().equals(savedSearch.getName()) && s.getSearchType().equals(savedSearch.getSearchType())) {
+ return s;
+ }
+ }
+
+ return savedSearch;
}
private void checkIfQueryAlreadyExists(AtlasUserSavedSearch savedSearch, AtlasUserProfile userProfile) throws AtlasBaseException {
for (AtlasUserSavedSearch exisingSearch : userProfile.getSavedSearches()) {
if (StringUtils.equals(exisingSearch.getOwnerName(), savedSearch.getOwnerName()) &&
- StringUtils.equals(exisingSearch.getName(), savedSearch.getName())) {
+ StringUtils.equals(exisingSearch.getName(), savedSearch.getName()) &&
+ exisingSearch.getSearchType().equals(savedSearch.getSearchType())) {
throw new AtlasBaseException(AtlasErrorCode.SAVED_SEARCH_ALREADY_EXISTS, savedSearch.getName(), savedSearch.getOwnerName());
}
}
@@ -120,8 +129,8 @@ public class UserProfileService {
return (profile != null) ? profile.getSavedSearches() : null;
}
- public AtlasUserSavedSearch getSavedSearch(String userName, String searchName) throws AtlasBaseException {
- AtlasUserSavedSearch ss = new AtlasUserSavedSearch(userName, searchName);
+ public AtlasUserSavedSearch getSavedSearch(String userName, String searchName, SavedSearchType searchType) throws AtlasBaseException {
+ AtlasUserSavedSearch ss = new AtlasUserSavedSearch(userName, searchName, searchType);
return dataAccess.load(ss);
}
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java b/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
index 4e83296..713dade 100644
--- a/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/userprofile/UserProfileServiceTest.java
@@ -37,6 +37,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import static org.apache.atlas.model.profile.AtlasUserSavedSearch.SavedSearchType.BASIC;
import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.loadModelFromJson;
import static org.testng.Assert.*;
@@ -77,7 +78,7 @@ public class UserProfileServiceTest {
}
@Test(dependsOnMethods = { "createsNewProfile", "savesQueryForAnNonExistentUser" }, expectedExceptions = AtlasBaseException.class)
- public void savesAlreadyExistingQueryForAnExistingUser() throws AtlasBaseException {
+ public void atteptsToAddAlreadyExistingQueryForAnExistingUser() throws AtlasBaseException {
SearchParameters expectedSearchParameter = getActualSearchParameters();
for (int i = 0; i < 2; i++) {
@@ -85,13 +86,20 @@ public class UserProfileServiceTest {
for (int j = 0; j < max_searches; j++) {
String queryName = getIndexBasedQueryName(j);
- AtlasUserProfile actual = userProfileService.addSavedSearch(new AtlasUserSavedSearch(userName, queryName, expectedSearchParameter));
+ AtlasUserSavedSearch expected = getDefaultSavedSearch(userName, queryName, expectedSearchParameter);
+ AtlasUserSavedSearch actual = userProfileService.addSavedSearch(expected);
+
assertNotNull(actual);
+ assertNotNull(actual.getGuid());
+ assertEquals(actual.getOwnerName(), expected.getOwnerName());
+ assertEquals(actual.getName(), expected.getName());
+ assertEquals(actual.getSearchType(), expected.getSearchType());
+ assertEquals(actual.getSearchParameters(), expected.getSearchParameters());
}
}
}
- @Test(dependsOnMethods = { "createsNewProfile", "savesQueryForAnNonExistentUser", "savesAlreadyExistingQueryForAnExistingUser" })
+ @Test(dependsOnMethods = { "createsNewProfile", "savesQueryForAnNonExistentUser", "atteptsToAddAlreadyExistingQueryForAnExistingUser" })
public void savesExistingQueryForAnExistingUser() throws AtlasBaseException {
SearchParameters expectedSearchParameter = getActualSearchParameters();
@@ -100,10 +108,10 @@ public class UserProfileServiceTest {
for (int j = 4; j < max_searches + 6; j++) {
String queryName = getIndexBasedQueryName(j);
- AtlasUserProfile actual = userProfileService.addSavedSearch(new AtlasUserSavedSearch(userName, queryName, expectedSearchParameter));
+ AtlasUserSavedSearch actual = userProfileService.addSavedSearch(getDefaultSavedSearch(userName, queryName, expectedSearchParameter));
assertNotNull(actual);
- AtlasUserSavedSearch savedSearch = userProfileService.getSavedSearch(userName, queryName);
+ AtlasUserSavedSearch savedSearch = userProfileService.getSavedSearch(userName, queryName, BASIC);
assertNotNull(savedSearch);
assertEquals(savedSearch.getSearchParameters(), expectedSearchParameter);
}
@@ -122,14 +130,19 @@ public class UserProfileServiceTest {
@Test(dependsOnMethods = "createsNewProfile")
public void savesQueryForAnNonExistentUser() throws AtlasBaseException {
- String expectedUserName = "firstXYZ";
+ String expectedUserName = getIndexBasedUserName(0);
String expectedQueryName = "testQuery";
SearchParameters expectedSearchParam = getActualSearchParameters();
+ AtlasUserSavedSearch expectedSavedSearch = getDefaultSavedSearch(expectedUserName, expectedQueryName, expectedSearchParam);
+
+ AtlasUserSavedSearch actual = userProfileService.addSavedSearch(expectedSavedSearch);
+ assertEquals(actual.getOwnerName(), expectedUserName);
+ assertEquals(actual.getName(), expectedQueryName);
+ }
- AtlasUserProfile actual = userProfileService.addSavedSearch(new AtlasUserSavedSearch(expectedUserName, expectedQueryName, expectedSearchParam));
- assertEquals(actual.getName(), expectedUserName);
- assertEquals(actual.getSavedSearches().size(), 1);
- assertEquals(actual.getSavedSearches().get(0).getName(), expectedQueryName);
+ private AtlasUserSavedSearch getDefaultSavedSearch(String userName, String queryName, SearchParameters expectedSearchParam) {
+ return new AtlasUserSavedSearch(userName, queryName,
+ BASIC, expectedSearchParam);
}
@Test(dependsOnMethods = "createsNewProfile")
@@ -143,7 +156,7 @@ public class UserProfileServiceTest {
saveQueries(userName, actualSearchParameter);
for (int i = 0; i < max_searches; i++) {
- AtlasUserSavedSearch savedSearch = userProfileService.getSavedSearch(userName, getIndexBasedQueryName(i));
+ AtlasUserSavedSearch savedSearch = userProfileService.getSavedSearch(userName, getIndexBasedQueryName(i), BASIC);
assertEquals(savedSearch.getName(), getIndexBasedQueryName(i));
assertEquals(savedSearch.getSearchParameters(), actualSearchParameter);
}
@@ -151,7 +164,7 @@ public class UserProfileServiceTest {
private void saveQueries(String userName, SearchParameters sp) throws AtlasBaseException {
for (int i = 0; i < max_searches; i++) {
- userProfileService.addSavedSearch(new AtlasUserSavedSearch(userName, getIndexBasedQueryName(i), sp));
+ userProfileService.addSavedSearch(getDefaultSavedSearch(userName, getIndexBasedQueryName(i), sp));
}
}
@@ -181,7 +194,7 @@ public class UserProfileServiceTest {
public void updateSearch() throws AtlasBaseException {
final String queryName = getIndexBasedQueryName(0);
String userName = getIndexBasedUserName(0);
- AtlasUserSavedSearch expected = userProfileService.getSavedSearch(userName, queryName);
+ AtlasUserSavedSearch expected = userProfileService.getSavedSearch(userName, queryName, BASIC);
assertNotNull(expected);
SearchParameters sp = expected.getSearchParameters();
@@ -199,11 +212,11 @@ public class UserProfileServiceTest {
final String queryName = getIndexBasedQueryName(1);
String userName = getIndexBasedUserName(0);
- AtlasUserSavedSearch expected = userProfileService.getSavedSearch(userName, queryName);
+ AtlasUserSavedSearch expected = userProfileService.getSavedSearch(userName, queryName, BASIC);
assertNotNull(expected);
userProfileService.deleteSavedSearch(expected.getGuid());
- userProfileService.getSavedSearch(userName, queryName);
+ userProfileService.getSavedSearch(userName, queryName, BASIC);
}
@Test(dependsOnMethods = {"createsNewProfile", "savesMultipleQueriesForUser", "verifyQueryNameListForUser"})
@@ -236,12 +249,12 @@ public class UserProfileServiceTest {
private void assertSaveLoadUserProfile(int i) throws AtlasBaseException {
String s = String.valueOf(i);
AtlasUserProfile expected = getAtlasUserProfile(i);
- userProfileService.saveUserProfile(expected);
- AtlasUserProfile actual = userProfileService.getUserProfile(expected.getName());
+ AtlasUserProfile actual = userProfileService.saveUserProfile(expected);
assertNotNull(actual);
assertEquals(expected.getName(), actual.getName());
assertEquals(expected.getFullName(), actual.getFullName());
+ assertNotNull(actual.getGuid());
}
public static AtlasUserProfile getAtlasUserProfile(Integer s) {
http://git-wip-us.apache.org/repos/asf/atlas/blob/4f1129bd/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
index ad595c8..aed82ae 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/DiscoveryREST.java
@@ -24,6 +24,7 @@ import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.AtlasSearchResult;
import org.apache.atlas.model.discovery.SearchParameters;
import org.apache.atlas.model.profile.AtlasUserSavedSearch;
+import org.apache.atlas.model.profile.AtlasUserSavedSearch.SavedSearchType;
import org.apache.atlas.utils.AtlasPerfTracer;
import org.apache.atlas.web.util.Servlets;
import org.apache.commons.collections.CollectionUtils;
@@ -321,25 +322,9 @@ public class DiscoveryREST {
}
}
- private boolean isEmpty(SearchParameters.FilterCriteria filterCriteria) {
- return filterCriteria == null ||
- (StringUtils.isEmpty(filterCriteria.getAttributeName()) && CollectionUtils.isEmpty(filterCriteria.getCriterion()));
- }
-
- private String escapeTypeName(String typeName) {
- String ret;
-
- if (StringUtils.startsWith(typeName, "`") && StringUtils.endsWith(typeName, "`")) {
- ret = typeName;
- } else {
- ret = String.format("`%s`", typeName);
- }
-
- return ret;
- }
-
/**
* @param savedSearch
+ * @return the saved search-object
* @throws AtlasBaseException
* @throws IOException
*/
@@ -347,36 +332,75 @@ public class DiscoveryREST {
@Path("saved")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
- public void createSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException, IOException {
+ public AtlasUserSavedSearch createSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException, IOException {
savedSearch.setOwnerName(Servlets.getUserName(httpServletRequest));
- atlasDiscoveryService.addSavedSearch(savedSearch);
+ AtlasPerfTracer perf = null;
+
+ try {
+ if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+ perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.createSavedSearch(ownerName=" + savedSearch.getOwnerName() + ", name=" + savedSearch.getName() + ", searchType=" + savedSearch.getSearchType() + ")");
+ }
+
+ return atlasDiscoveryService.addSavedSearch(savedSearch);
+ } finally {
+ AtlasPerfTracer.log(perf);
+ }
}
- /**
+ /***
+ *
* @param savedSearch
+ * @return the updated search-object
* @throws AtlasBaseException
- * @throws IOException
*/
@PUT
@Path("saved")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
- public void updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
- atlasDiscoveryService.updateSavedSearch(savedSearch);
+ public AtlasUserSavedSearch updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
+ savedSearch.setOwnerName(Servlets.getUserName(httpServletRequest));
+
+ AtlasPerfTracer perf = null;
+
+ try {
+ if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+ perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.updateSavedSearch(ownerName=" + savedSearch.getOwnerName() + ", name=" + savedSearch.getName() + ", searchType=" + savedSearch.getSearchType() + ")");
+ }
+
+ return atlasDiscoveryService.updateSavedSearch(savedSearch);
+ } finally {
+ AtlasPerfTracer.log(perf);
+ }
}
/**
+ *
+ * @param userName User for whom the search is retrieved
* @param searchName Name of the saved search
* @return
+ * @throws AtlasBaseException
*/
@GET
- @Path("saved/{name}")
+ @Path("saved/{type}/{name}")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
- public AtlasUserSavedSearch getSavedSearch(@QueryParam("user") String userName, @PathParam("name") String searchName) throws AtlasBaseException {
+ public AtlasUserSavedSearch getSavedSearch(@PathParam("type") String searchType,
+ @PathParam("name") String searchName,
+ @QueryParam("user") String userName) throws AtlasBaseException {
userName = StringUtils.isBlank(userName) ? Servlets.getUserName(httpServletRequest) : userName;
- return atlasDiscoveryService.getSavedSearch(userName, searchName);
+
+ AtlasPerfTracer perf = null;
+
+ try {
+ if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+ perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.getSavedSearch(user=" + userName + ", name=" + searchName + ", type=" + searchType + ")");
+ }
+
+ return atlasDiscoveryService.getSavedSearch(userName, searchName, SavedSearchType.to(searchType));
+ } finally {
+ AtlasPerfTracer.log(perf);
+ }
}
/**
@@ -388,7 +412,18 @@ public class DiscoveryREST {
@Produces(Servlets.JSON_MEDIA_TYPE)
public List<AtlasUserSavedSearch> getSavedSearches(@QueryParam("user") String userName) throws AtlasBaseException {
userName = StringUtils.isBlank(userName) ? Servlets.getUserName(httpServletRequest) : userName;
- return atlasDiscoveryService.getSavedSearches(userName);
+
+ AtlasPerfTracer perf = null;
+
+ try {
+ if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+ perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.getSavedSearches(user=" + userName + ")");
+ }
+
+ return atlasDiscoveryService.getSavedSearches(userName);
+ } finally {
+ AtlasPerfTracer.log(perf);
+ }
}
/**
@@ -399,6 +434,41 @@ public class DiscoveryREST {
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
public void deleteSavedSearch(@PathParam("guid") String guid) throws AtlasBaseException {
- atlasDiscoveryService.deleteSavedSearch(guid);
+ AtlasPerfTracer perf = null;
+
+ try {
+ if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+ perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "DiscoveryREST.deleteSavedSearch(guid=" + guid + ")");
+ }
+
+ AtlasUserSavedSearch savedSearch = atlasDiscoveryService.getSavedSearch(guid);
+
+ // block attempt to delete another user's saved-search
+ if (!StringUtils.equals(savedSearch.getOwnerName(), Servlets.getUserName(httpServletRequest))) {
+ throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "invalid data");
+ }
+
+ atlasDiscoveryService.deleteSavedSearch(guid);
+ } finally {
+ AtlasPerfTracer.log(perf);
+ }
+ }
+
+
+ private boolean isEmpty(SearchParameters.FilterCriteria filterCriteria) {
+ return filterCriteria == null ||
+ (StringUtils.isEmpty(filterCriteria.getAttributeName()) && CollectionUtils.isEmpty(filterCriteria.getCriterion()));
+ }
+
+ private String escapeTypeName(String typeName) {
+ String ret;
+
+ if (StringUtils.startsWith(typeName, "`") && StringUtils.endsWith(typeName, "`")) {
+ ret = typeName;
+ } else {
+ ret = String.format("`%s`", typeName);
+ }
+
+ return ret;
}
}
[3/7] atlas git commit: ATLAS-2132: incorrect error for invalid file
path/unreadable file provided during import
Posted by ma...@apache.org.
ATLAS-2132: incorrect error for invalid file path/unreadable file provided during import
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
(cherry picked from commit 67c04c63e1126791ab8537e2a8e8411f0b9e6897)
Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/ceb5c0cd
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/ceb5c0cd
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/ceb5c0cd
Branch: refs/heads/branch-0.8
Commit: ceb5c0cd90aa94d6836bb5f14154e5c5934e7ed2
Parents: 2e138da
Author: Ashutosh Mestry <am...@apache.org>
Authored: Mon Sep 18 22:22:15 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Thu Sep 21 19:10:04 2017 -0700
----------------------------------------------------------------------
.../atlas/repository/impexp/ImportService.java | 8 ++-
.../repository/impexp/ImportServiceTest.java | 55 +++++++++++++++++---
2 files changed, 53 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/atlas/blob/ceb5c0cd/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
index 650741e..c976c59 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
@@ -36,6 +36,7 @@ import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
@Component
public class ImportService {
@@ -108,7 +109,7 @@ public class ImportService {
public AtlasImportResult run(AtlasImportRequest request, String userName, String hostName, String requestingIP)
throws AtlasBaseException {
- String fileName = (String) request.getFileName();
+ String fileName = request.getFileName();
if (StringUtils.isBlank(fileName)) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "FILENAME parameter not found");
@@ -122,7 +123,6 @@ public class ImportService {
String transforms = MapUtils.isNotEmpty(request.getOptions()) ? request.getOptions().get(AtlasImportRequest.TRANSFORMS_KEY) : null;
File file = new File(fileName);
ZipSource source = new ZipSource(new ByteArrayInputStream(FileUtils.readFileToByteArray(file)), ImportTransforms.fromJson(transforms));
-
result = run(source, request, userName, hostName, requestingIP);
} catch (AtlasBaseException excp) {
LOG.error("import(user={}, from={}, fileName={}): failed", userName, requestingIP, excp);
@@ -132,6 +132,10 @@ public class ImportService {
LOG.error("import(user={}, from={}, fileName={}): file not found", userName, requestingIP, excp);
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, fileName + ": file not found");
+ } catch (IOException excp) {
+ LOG.error("import(user={}, from={}, fileName={}): cannot read file", userName, requestingIP, excp);
+
+ throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, fileName + ": cannot read file");
} catch (Exception excp) {
LOG.error("import(user={}, from={}, fileName={}): failed", userName, requestingIP, excp);
http://git-wip-us.apache.org/repos/asf/atlas/blob/ceb5c0cd/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
index 923b681..035ddac 100644
--- a/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/impexp/ImportServiceTest.java
@@ -27,6 +27,8 @@ import org.apache.atlas.model.impexp.AtlasImportRequest;
import org.apache.atlas.store.AtlasTypeDefStore;
import org.apache.atlas.type.AtlasClassificationType;
import org.apache.atlas.type.AtlasTypeRegistry;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.ITestContext;
@@ -40,6 +42,8 @@ import java.util.HashMap;
import java.util.Map;
import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -72,7 +76,7 @@ public class ImportServiceTest {
@Test(dataProvider = "sales")
public void importDB1(ZipSource zipSource) throws AtlasBaseException, IOException {
- loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
+ loadBaseModel();
runAndVerifyQuickStart_v1_Import(importService, zipSource);
}
@@ -83,7 +87,7 @@ public class ImportServiceTest {
@Test(dataProvider = "reporting")
public void importDB2(ZipSource zipSource) throws AtlasBaseException, IOException {
- loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
+ loadBaseModel();
runAndVerifyQuickStart_v1_Import(importService, zipSource);
}
@@ -94,7 +98,7 @@ public class ImportServiceTest {
@Test(dataProvider = "logging")
public void importDB3(ZipSource zipSource) throws AtlasBaseException, IOException {
- loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
+ loadBaseModel();
runAndVerifyQuickStart_v1_Import(importService, zipSource);
}
@@ -105,7 +109,7 @@ public class ImportServiceTest {
@Test(dataProvider = "salesNewTypeAttrs", dependsOnMethods = "importDB1")
public void importDB4(ZipSource zipSource) throws AtlasBaseException, IOException {
- loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
+ loadBaseModel();
runImportWithParameters(importService, getDefaultImportRequest(), zipSource);
}
@@ -154,8 +158,8 @@ public class ImportServiceTest {
@Test(dataProvider = "ctas")
public void importCTAS(ZipSource zipSource) throws IOException, AtlasBaseException {
- loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
- loadModelFromJson("0030-hive_model.json", typeDefStore, typeRegistry);
+ loadBaseModel();
+ loadHiveModel();
runImportWithNoParameters(importService, zipSource);
}
@@ -168,8 +172,8 @@ public class ImportServiceTest {
@Test(dataProvider = "hdfs_path1", expectedExceptions = AtlasBaseException.class)
public void importHdfs_path1(ZipSource zipSource) throws IOException, AtlasBaseException {
- loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
- loadModelFromJson("0020-fs_model.json", typeDefStore, typeRegistry);
+ loadBaseModel();
+ loadFsModel();
loadModelFromResourcesJson("tag1.json", typeDefStore, typeRegistry);
try {
@@ -182,4 +186,39 @@ public class ImportServiceTest {
throw e;
}
}
+
+ @Test
+ public void importServiceProcessesIOException() {
+ ImportService importService = new ImportService(typeDefStore, typeRegistry, null);
+ AtlasImportRequest req = mock(AtlasImportRequest.class);
+
+ Answer<Map> answer = new Answer<Map>() {
+ @Override
+ public Map answer(InvocationOnMock invocationOnMock) throws Throwable {
+ throw new IOException("file is read only");
+ }
+ };
+
+ when(req.getFileName()).thenReturn("some-file.zip");
+ when(req.getOptions()).thenAnswer(answer);
+
+ try {
+ importService.run(req, "a", "b", "c");
+ }
+ catch (AtlasBaseException ex) {
+ assertEquals(ex.getAtlasErrorCode().getErrorCode(), AtlasErrorCode.INVALID_PARAMETERS.getErrorCode());
+ }
+ }
+
+ private void loadBaseModel() throws IOException, AtlasBaseException {
+ loadModelFromJson("0010-base_model.json", typeDefStore, typeRegistry);
+ }
+
+ private void loadFsModel() throws IOException, AtlasBaseException {
+ loadModelFromJson("0020-fs_model.json", typeDefStore, typeRegistry);
+ }
+
+ private void loadHiveModel() throws IOException, AtlasBaseException {
+ loadModelFromJson("0030-hive_model.json", typeDefStore, typeRegistry);
+ }
}