ATLAS-4106: Add REST API debug metrics to Atlas

Co-authored-by: Jayendra Parab <jayendra@freestoneinfotech.com>

Signed-off-by: Sarath Subramanian <sarath@apache.org>
This commit is contained in:
mayanknj 2021-04-29 22:35:34 -07:00 committed by Sarath Subramanian
parent 85e3c5cf64
commit 8077863b2f
46 changed files with 2170 additions and 24 deletions

View File

@ -21,8 +21,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy
public class CommonConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(CommonConfiguration.class);

View File

@ -0,0 +1,32 @@
/**
* 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.
*/
package org.apache.atlas.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Timed {
String value() default "";
}

View File

@ -254,6 +254,10 @@
overflow: initial;
}
.tab-content>.tab-pane.active.debug-metrics {
padding: 5px 20px 15px 20px;
}
.advancedInfo {
margin-left: 5px;
cursor: pointer;
@ -550,6 +554,7 @@ div.columnmanager-dropdown-container {
}
}
}
.dropzone .dz-preview .dz-details .dz-filename {
padding-top: 20px;
}

View File

@ -122,7 +122,8 @@ tr.empty {
.debuggging-table-header {
padding-right: 0px !important;
button{
button {
float: right;
}
}
@ -314,4 +315,21 @@ td {
&>div {
flex-grow: 1;
}
}
.debug-metrics-table table {
tr th:not(:first-child),
tr td:not(:first-child) {
text-align: center !important;
button {
margin: 0 auto;
}
}
}
.debug-btn-wrapper {
margin-bottom: 5px;
z-index: 2;
}

View File

@ -280,6 +280,9 @@ require(['App',
if (response['atlas.ui.date.timezone.format.enabled'] !== undefined) {
Globals.isTimezoneFormatEnabled = response['atlas.ui.date.timezone.format.enabled'];
}
if (response['atlas.debug.metrics.enabled'] !== undefined) {
Globals.isDebugMetricsEnabled = response["atlas.debug.metrics.enabled"];
}
}
--that.asyncFetchCounter;
startApp();
@ -359,4 +362,4 @@ require(['App',
startApp();
}
});
});
});

View File

@ -46,6 +46,8 @@ define([
//Administrator page
'!/administrator': 'administrator',
'!/administrator/businessMetadata/:id': 'businessMetadataDetailPage',
//Debug Metrics
'!/debugMetrics': 'debugMetrics',
// Default
'*actions': 'defaultAction'
},
@ -355,6 +357,29 @@ define([
App.rNContent.show(new AdministratorLayoutView(_.extend({ value: paramObj, guid: null }, options)));
});
},
debugMetrics: function() {
var that = this;
require(["views/site/Header", "views/site/SideNavLayoutView", 'views/dev_debug/DebugMetricsLayoutView'], function(Header, SideNavLayoutView, DebugMetricsLayoutView) {
var paramObj = Utils.getUrlState.getQueryParams(),
options = _.extend({}, that.preFetchedCollectionLists, that.sharedObj, that.ventObj);
that.renderViewIfNotExists(that.getHeaderOptions(Header));
that.renderViewIfNotExists({
view: App.rSideNav,
manualRender: function() {
this.view.currentView.selectTab();
if (Utils.getUrlState.isTagTab()) {
this.view.currentView.RTagLayoutView.currentView.manualRender();
} else if (Utils.getUrlState.isGlossaryTab()) {
this.view.currentView.RGlossaryLayoutView.currentView.manualRender(_.extend({ "isTrigger": true, "value": paramObj }));
}
},
render: function() {
return new SideNavLayoutView(options);
}
});
App.rNContent.show(new DebugMetricsLayoutView(options));
});
},
businessMetadataDetailPage: function(guid) {
var that = this;
require(["views/site/Header", "views/site/SideNavLayoutView", "views/business_metadata/BusinessMetadataContainerLayoutView", ], function(Header, SideNavLayoutView, BusinessMetadataContainerLayoutView) {

View File

@ -0,0 +1,30 @@
<!--
* 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" style=" margin:0px;">
<div class="col-sm-12 default-tab">
<ul class="nav nav-tabs" data-id="tab-list">
<li role="debugMetrics" class="tab active"><a href="#tab-debugMetrics" aria-controls="tab-debugMetrics" role="tab" data-toggle="tab">REST API Metrics</a> </li>
</ul>
</div>
</div>
<div class="tab-content admin-details">
<div id="tab-debugMetrics" role="debugMetrics" class="tab-pane active animated fadeIn debug-metrics">
<div id="r_debugMetricsLayoutView">
</div>
</div>
</div>
</div>

View File

@ -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="metrics-details" data-id="metricsTablePage">
<div class="col-sm-12 debug-btn-wrapper">
<button type="button" class="btn btn-action btn-sm pull-right typeLOV" title="" data-id="refreshMetricsBtn" data-original-title="Refresh"><i class="fa fa-refresh"></i></button>
</div>
<div class="position-relative">
<div class="tableOverlay"></div>
<div class='attr-filter-overlay hide'></div>
<div class="debug-metrics-table metrics-details">
<div id="r_debugMetricsTableLayoutView"></div>
</div>
</div>
</div>

View File

@ -33,7 +33,6 @@
</div>
</td>
<td>
<!-- <div class="btn-group pull-right header-menu"> -->
<table class="header-menu">
<tr>
<td><a class="show-stat" href="javascript:void(0);" title="Statistics"><i class="fa fa-bar-chart"></i></a></td>
@ -66,6 +65,9 @@
<li><a target="_blank" href="http://atlas.apache.org/">Documentation</a></li>
<li><a target="_blank" href="{{apiDocUrl}}">API Documentation</a></li>
<li class="aboutAtlas"><a href="javascript:void(0)">About</a></li>
{{#if isDebugMetricsEnabled}}
<li class="show-debug"><a href="javascript:void(0)" data-id="showDebug">Debug</a></li>
{{/if}}
</ul>
</li>
<li role="separator" class="divider"></li>
@ -80,4 +82,4 @@
</td>
</tr>
</table>
</header>
</header>

View File

@ -29,7 +29,8 @@ define(["require"], function(require) {
tagUrl: "#!/tag",
searchUrl: "#!/search",
glossaryUrl: "#!/glossary",
administratorUrl: "#!/administrator"
administratorUrl: "#!/administrator",
debugMetricsUrl: "#!/debugMetrics"
},
detailPageState: {}
};
@ -46,5 +47,7 @@ define(["require"], function(require) {
Globals.dateFormat = "MM/DD/YYYY";
Globals.isTimezoneFormatEnabled = true;
Globals.isDebugMetricsEnabled = false;
return Globals;
});
});

View File

@ -46,6 +46,9 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
metricsApiUrl: function() {
return this.baseUrl + '/admin/metrics'
},
debugMetricsApiUrl: function() {
return this.baseUrl + '/admin/debug/metrics'
},
migrationStatusApiUrl: function() {
return this.baseUrl + '/admin/status'
},
@ -260,4 +263,4 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
});
return UrlLinks;
});
});

View File

@ -341,6 +341,8 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
urlUpdate['glossaryUrl'] = options.url;
} else if (Utils.getUrlState.isAdministratorTab(options.url)) {
urlUpdate['administratorUrl'] = options.url;
} else if (Utils.getUrlState.isDebugMetricsTab(options.url)) {
urlUpdate['debugMetricsUrl'] = options.url;
}
$.extend(Globals.saveApplicationState.tabState, urlUpdate);
}
@ -392,6 +394,12 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
matchString: "administrator"
});
},
isDebugMetricsTab: function(url) {
return this.checkTabUrl({
url: url,
matchString: "debugMetrics"
});
},
isGlossaryTab: function(url) {
return this.checkTabUrl({
url: url,

View File

@ -0,0 +1,86 @@
/**
* 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/dev_debug/DebugMetricsLayoutView_tmpl',
'utils/Utils'
], function(require, Backbone, DebugMetricsLayoutView_tmpl, Utils) {
'use strict';
var DebugMetricsLayoutView = Backbone.Marionette.LayoutView.extend(
/** @lends DebugMetricsLayoutView */
{
_viewName: 'DebugMetricsLayoutView',
template: DebugMetricsLayoutView_tmpl,
/** Layout sub regions */
regions: {
RDebugMetricsLayoutView: "#r_debugMetricsLayoutView"
},
/** ui selector cache */
ui: {
tablist: '[data-id="tab-list"] li'
},
/** ui events hash */
events: function() {
var events = {};
events["click " + this.ui.tablist] = function(e) {
var tabValue = $(e.currentTarget).attr('role');
Utils.setUrl({
url: Utils.getUrlState.getQueryUrl().queyParams[0],
urlParams: { tabActive: tabValue || 'properties' },
mergeBrowserUrl: false,
trigger: false,
updateTabState: true
});
};
return events;
},
/**
* @constructs
*/
initialize: function(options) {
_.extend(this, _.pick(options, 'value'));
},
onShow: function() {
if (this.value && this.value.tabActive) {
this.$('.nav.nav-tabs').find('[role="' + this.value.tabActive + '"]').addClass('active').siblings().removeClass('active');
this.$('.tab-content').find('[role="' + this.value.tabActive + '"]').addClass('active').siblings().removeClass('active');
$("html, body").animate({ scrollTop: (this.$('.tab-content').offset().top + 1200) }, 1000);
}
},
bindEvents: function() {},
onRender: function() {
this.metrice2LayoutView();
this.bindEvents();
},
metrice2LayoutView: function(obj) {
var that = this;
require(['views/site/DebugMetricsTableLayoutView'], function(DebugMetricsTableLayoutView) {
that.RDebugMetricsLayoutView.show(new DebugMetricsTableLayoutView());
});
}
});
return DebugMetricsLayoutView;
});

View File

@ -0,0 +1,174 @@
/**
* 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/site/DebugMetricsTableLayoutView_tmpl',
'utils/UrlLinks',
'collection/VEntityList',
'utils/CommonViewFunction',
'utils/Utils'
], function(require, Backbone, DebugMetricsTableLayoutViewTmpl, UrlLinks, VEntityList, CommonViewFunction, Utils) {
'use strict';
var DebugMetricsTableLayoutView = Backbone.Marionette.LayoutView.extend(
/** @lends DebugMetricsTableLayoutView */
{
_viewName: 'DebugMetricsTableLayoutView',
template: DebugMetricsTableLayoutViewTmpl,
/** Layout sub regions */
regions: {
RDebugMetricsTableLayoutView: "#r_debugMetricsTableLayoutView"
},
/** ui selector cache */
ui: {
refreshMetricsBtn: '[data-id="refreshMetricsBtn"]'
},
/** ui events hash */
events: function() {
var events = {};
events["click " + this.ui.refreshMetricsBtn] = function(e) {
this.currPage = 1;
this.limit = 26;
this.debugMetricsCollection.state.pageSize = 25;
this.debugMetricsCollection.state.currentPage = 0;
this.fetchMetricData();
};
return events;
},
/**
* intialize a new DebugMetricsTableLayoutView Layout
* @constructs
*/
initialize: function(options) {
_.extend(this, options);
var that = this;
this.DATA_MAX_LENGTH = 25;
this.debugMetricsCollection = new VEntityList();
this.debugMetricsCollection.url = UrlLinks.debugMetricsApiUrl();
this.debugMetricsCollection.modelAttrName = "data";
this.commonTableOptions = {
collection: this.debugMetricsCollection,
includeFilter: false,
includePagination: true,
includeFooterRecords: true,
includePageSize: true,
includeGotoPage: true,
includeAtlasTableSorting: true,
includeTableLoader: true,
includeColumnManager: false,
gridOpts: {
className: "table table-hover backgrid table-quickMenu",
emptyText: 'No records found!'
},
filterOpts: {},
paginatorOpts: {}
};
this.currPage = 1;
this.limit = 26;
},
bindEvents: function() {
var that = this;
},
onRender: function() {
this.bindEvents();
this.$('.debug-metrics-table').show();
this.fetchMetricData();
},
fetchMetricData: function(options) {
var that = this;
this.debugMetricsCollection.fetch({
success: function(data) {
var data = _.first(data.toJSON()),
metricsDataKeys = data ? Object.keys(data) : null;
that.debugMetricsCollection.fullCollection.reset();
_.each(metricsDataKeys.sort(), function(keyName) {
that.debugMetricsCollection.add(data[keyName]);
});
},
complete: function(data) {
that.renderTableLayoutView();
}
});
},
renderTableLayoutView: function() {
var that = this;
require(['utils/TableLayout'], function(TableLayout) {
var cols = new Backgrid.Columns(that.getAuditTableColumns());
that.RDebugMetricsTableLayoutView.show(new TableLayout(_.extend({}, that.commonTableOptions, {
columns: cols
})));
if (!(that.debugMetricsCollection.models.length < that.limit)) {
that.RDebugMetricsTableLayoutView.$el.find('table tr').last().hide();
}
});
},
getAuditTableColumns: function() {
var that = this;
return this.debugMetricsCollection.constructor.getTableCols({
name: {
label: "Name",
cell: "html",
sortable: true,
editable: false
},
numops: {
label: "Count",
cell: "html",
sortable: true,
editable: false
},
minTime: {
label: "Min Time (secs)",
cell: "html",
sortable: true,
editable: false,
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
return parseFloat((rawValue % 1000) / 100).toFixed(3);
}
})
},
maxTime: {
label: "Max Time (secs)",
cell: "html",
sortable: true,
editable: false,
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
return parseFloat((rawValue % 1000) / 100).toFixed(3);
}
})
},
avgTime: {
label: "Average Time (secs)",
cell: "html",
sortable: true,
editable: false,
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
return parseFloat((rawValue % 1000) / 100).toFixed(3);
}
})
}
}, this.debugMetricsCollection);
}
});
return DebugMetricsTableLayoutView;
});

View File

@ -34,6 +34,7 @@ define(['require',
glossaryImportTempUrl: UrlLinks.glossaryImportTempUrl(),
businessMetadataImportTempUrl: UrlLinks.businessMetadataImportTempUrl(),
apiDocUrl: UrlLinks.apiDocUrl(),
isDebugMetricsEnabled: Globals.isDebugMetricsEnabled
};
},
ui: {
@ -43,6 +44,7 @@ define(['require',
clearGlobalSearch: "[data-id='clearGlobalSearch']",
signOut: "[data-id='signOut']",
administrator: "[data-id='administrator']",
showDebug: "[data-id='showDebug']",
uiSwitch: "[data-id='uiSwitch']",
glossaryImport: "[data-id='glossaryImport']",
businessMetadataImport: "[data-id='businessMetadataImport']"
@ -91,6 +93,14 @@ define(['require',
events['click ' + this.ui.businessMetadataImport] = function() {
this.onClickImport()
};
events['click ' + this.ui.showDebug] = function() {
Utils.setUrl({
url: "#!/debugMetrics",
mergeBrowserUrl: false,
trigger: true,
updateTabState: true
});
};
return events;
},
@ -320,4 +330,4 @@ define(['require',
}
});
return Header;
});
});

View File

@ -116,7 +116,7 @@ define(['require',
that.$('.tabs').find('li a[aria-controls="tab-' + view + '"]').parents('li').addClass('active').siblings().removeClass('active');
that.$('.tab-content').find('div#tab-' + view).addClass('active').siblings().removeClass('active');
};
if (Utils.getUrlState.isSearchTab() || Utils.getUrlState.isInitial() || Utils.getUrlState.isAdministratorTab()) {
if (Utils.getUrlState.isSearchTab() || Utils.getUrlState.isInitial() || Utils.getUrlState.isAdministratorTab() || Utils.getUrlState.isDebugMetricsTab()) {
activeTab({ "view": "search" });
} else if (Utils.getUrlState.isTagTab()) {
activeTab({ "view": "classification" });

View File

@ -258,6 +258,10 @@
overflow: initial;
}
.tab-content>.tab-pane.active.debug-metrics {
padding: 5px 20px 15px 20px;
}
.advancedInfo {
margin-left: 5px;
cursor: pointer;

View File

@ -315,4 +315,21 @@ td {
&>div {
flex-grow: 1;
}
}
.debug-metrics-table table {
tr th:not(:first-child),
tr td:not(:first-child) {
text-align: center !important;
button {
margin: 0 auto;
}
}
}
.debug-btn-wrapper {
margin-bottom: 5px;
z-index: 2;
}

View File

@ -309,6 +309,9 @@ require(['App',
if (response['atlas.ui.date.timezone.format.enabled'] !== undefined) {
Globals.isTimezoneFormatEnabled = response['atlas.ui.date.timezone.format.enabled'];
}
if (response['atlas.debug.metrics.enabled'] !== undefined) {
Globals.isDebugMetricsEnabled = response["atlas.debug.metrics.enabled"];
}
}
--that.asyncFetchCounter;
startApp();
@ -390,4 +393,4 @@ require(['App',
startApp();
}
});
});
});

View File

@ -47,6 +47,8 @@ define([
//Audit table
'!/administrator': 'administrator',
'!/administrator/businessMetadata/:id': 'businessMetadataDetailPage',
//Debug Metrics
'!/debugMetrics': 'debugMetrics',
// Default
"*actions": "defaultAction"
},
@ -425,9 +427,9 @@ define([
App.rContent.show(new AdministratorLayoutView(_.extend({ value: paramObj, guid: null }, options)));
});
},
devDebugging: function() {
debugMetrics: function() {
var that = this;
require(["views/site/Header", "views/site/SideNavLayoutView", 'views/dev_debug/DevDebuggingLayoutView'], function(Header, SideNavLayoutView, DevDebuggingLayoutView) {
require(["views/site/Header", "views/site/SideNavLayoutView", 'views/dev_debug/DebugMetricsLayoutView'], function(Header, SideNavLayoutView, DebugMetricsLayoutView) {
var paramObj = Utils.getUrlState.getQueryParams(),
options = _.extend({}, that.preFetchedCollectionLists, that.sharedObj, that.ventObj);
that.renderViewIfNotExists(that.getHeaderOptions(Header));
@ -440,10 +442,9 @@ define([
return new SideNavLayoutView(options);
}
});
App.rContent.show(new DevDebuggingLayoutView(options));
App.rContent.show(new DebugMetricsLayoutView(options));
});
},
businessMetadataDetailPage: function(guid) {
var that = this;
require(["views/site/Header", "views/site/SideNavLayoutView", "views/business_metadata/BusinessMetadataContainerLayoutView", ], function(Header, SideNavLayoutView, BusinessMetadataContainerLayoutView) {

View File

@ -0,0 +1,30 @@
<!--
* 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" style=" margin:0px;">
<div class="col-sm-12 default-tab">
<ul class="nav nav-tabs" data-id="tab-list">
<li role="debugMetrics" class="tab active"><a href="#tab-debugMetrics" aria-controls="tab-debugMetrics" role="tab" data-toggle="tab">REST API Metrics</a> </li>
</ul>
</div>
</div>
<div class="tab-content admin-details">
<div id="tab-debugMetrics" role="debugMetrics" class="tab-pane active animated fadeIn debug-metrics">
<div id="r_debugMetricsLayoutView">
</div>
</div>
</div>
</div>

View File

@ -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="metrics-details" data-id="metricsTablePage">
<div class="col-sm-12 debug-btn-wrapper">
<button type="button" class="btn btn-action btn-sm pull-right typeLOV" title="" data-id="refreshMetricsBtn" data-original-title="Refresh"><i class="fa fa-refresh"></i></button>
</div>
<div class="position-relative">
<div class="tableOverlay"></div>
<div class='attr-filter-overlay hide'></div>
<div class="debug-metrics-table metrics-details">
<div id="r_debugMetricsTableLayoutView"></div>
</div>
</div>
</div>

View File

@ -49,6 +49,9 @@
<li><a target="_blank" href="http://atlas.apache.org/">Documentation</a></li>
<li><a target="_blank" href="{{apiDocUrl}}">API Documentation</a></li>
<li class="aboutAtlas"><a href="javascript:void(0)">About</a></li>
{{#if isDebugMetricsEnabled}}
<li class="show-debug"><a href="javascript:void(0)" data-id="showDebug">Debug</a></li>
{{/if}}
</ul>
</li>
<li class="divider"></li>
@ -62,4 +65,4 @@
</tr>
</table>
</header>
<div id="r_filterBrowserLayoutView"></div>
<div id="r_filterBrowserLayoutView"></div>

View File

@ -29,7 +29,8 @@ define(["require"], function(require) {
tagUrl: "#!/tag",
searchUrl: "#!/search",
glossaryUrl: "#!/glossary",
administratorUrl: "#!/administrator"
administratorUrl: "#!/administrator",
debugMetricsUrl: "#!/debugMetrics"
},
detailPageState: {}
};
@ -46,5 +47,7 @@ define(["require"], function(require) {
Globals.dateFormat = "MM/DD/YYYY";
Globals.isTimezoneFormatEnabled = true;
Globals.isDebugMetricsEnabled = false;
return Globals;
});
});

View File

@ -46,6 +46,12 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
metricsApiUrl: function() {
return this.baseUrl + '/admin/metrics'
},
debugMetricsApiUrl: function() {
return this.baseUrl + '/admin/debug/metrics'
},
regitrydataDefApiUrl: function(name) {
return this.baseUrlV2 + '/entity/getRegistryData';
},
rootEntityDefUrl: function(name) {
return this.baseUrlV2 + '/types/entitydef/name/' + name;
},
@ -248,4 +254,4 @@ define(['require', 'utils/Enums', 'utils/Utils', 'underscore'], function(require
});
return UrlLinks;
});
});

View File

@ -348,8 +348,13 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
urlUpdate['searchUrl'] = options.url;
} else if (Utils.getUrlState.isGlossaryTab(options.url)) {
urlUpdate['glossaryUrl'] = options.url;
} else if (Utils.getUrlState.isBMDetailPage(options.url)) {
urlUpdate['bmDetailPageUrl'] = options.url;
urlUpdate['administratorUrl'] = options.url;
} else if (Utils.getUrlState.isAdministratorTab(options.url)) {
urlUpdate['administratorUrl'] = options.url;
} else if (Utils.getUrlState.isDebugMetricsTab(options.url)) {
urlUpdate['debugMetricsUrl'] = options.url;
}
$.extend(Globals.saveApplicationState.tabState, urlUpdate);
}
@ -397,6 +402,16 @@ define(['require', 'utils/Globals', 'pnotify', 'utils/Messages', 'utils/Enums',
matchString: "administrator"
});
},
isBMDetailPage: function(url) {
var quey = this.getQueryUrl(url);
return (quey.hash.indexOf("businessMetadata") > -1) ? true : false;
},
isDebugMetricsTab: function(url) {
return this.checkTabUrl({
url: url,
matchString: "debugMetrics"
});
},
isGlossaryTab: function(url) {
return this.checkTabUrl({
url: url,

View File

@ -0,0 +1,86 @@
/**
* 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/dev_debug/DebugMetricsLayoutView_tmpl',
'utils/Utils'
], function(require, Backbone, DebugMetricsLayoutView_tmpl, Utils) {
'use strict';
var DebugMetricsLayoutView = Backbone.Marionette.LayoutView.extend(
/** @lends DebugMetricsLayoutView */
{
_viewName: 'DebugMetricsLayoutView',
template: DebugMetricsLayoutView_tmpl,
/** Layout sub regions */
regions: {
RDebugMetricsLayoutView: "#r_debugMetricsLayoutView"
},
/** ui selector cache */
ui: {
tablist: '[data-id="tab-list"] li'
},
/** ui events hash */
events: function() {
var events = {};
events["click " + this.ui.tablist] = function(e) {
var tabValue = $(e.currentTarget).attr('role');
Utils.setUrl({
url: Utils.getUrlState.getQueryUrl().queyParams[0],
urlParams: { tabActive: tabValue || 'properties' },
mergeBrowserUrl: false,
trigger: false,
updateTabState: true
});
};
return events;
},
/**
* @constructs
*/
initialize: function(options) {
_.extend(this, _.pick(options, 'value'));
},
onShow: function() {
if (this.value && this.value.tabActive) {
this.$('.nav.nav-tabs').find('[role="' + this.value.tabActive + '"]').addClass('active').siblings().removeClass('active');
this.$('.tab-content').find('[role="' + this.value.tabActive + '"]').addClass('active').siblings().removeClass('active');
$("html, body").animate({ scrollTop: (this.$('.tab-content').offset().top + 1200) }, 1000);
}
},
bindEvents: function() {},
onRender: function() {
this.metrice2LayoutView();
this.bindEvents();
},
metrice2LayoutView: function(obj) {
var that = this;
require(['views/site/DebugMetricsTableLayoutView'], function(DebugMetricsTableLayoutView) {
that.RDebugMetricsLayoutView.show(new DebugMetricsTableLayoutView());
});
}
});
return DebugMetricsLayoutView;
});

View File

@ -0,0 +1,174 @@
/**
* 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/site/DebugMetricsTableLayoutView_tmpl',
'utils/UrlLinks',
'collection/VEntityList',
'utils/CommonViewFunction',
'utils/Utils'
], function(require, Backbone, DebugMetricsTableLayoutViewTmpl, UrlLinks, VEntityList, CommonViewFunction, Utils) {
'use strict';
var DebugMetricsTableLayoutView = Backbone.Marionette.LayoutView.extend(
/** @lends DebugMetricsTableLayoutView */
{
_viewName: 'DebugMetricsTableLayoutView',
template: DebugMetricsTableLayoutViewTmpl,
/** Layout sub regions */
regions: {
RDebugMetricsTableLayoutView: "#r_debugMetricsTableLayoutView"
},
/** ui selector cache */
ui: {
refreshMetricsBtn: '[data-id="refreshMetricsBtn"]'
},
/** ui events hash */
events: function() {
var events = {};
events["click " + this.ui.refreshMetricsBtn] = function(e) {
this.currPage = 1;
this.limit = 26;
this.debugMetricsCollection.state.pageSize = 25;
this.debugMetricsCollection.state.currentPage = 0;
this.fetchMetricData();
};
return events;
},
/**
* intialize a new DebugMetricsTableLayoutView Layout
* @constructs
*/
initialize: function(options) {
_.extend(this, options);
var that = this;
this.DATA_MAX_LENGTH = 25;
this.debugMetricsCollection = new VEntityList();
this.debugMetricsCollection.url = UrlLinks.debugMetricsApiUrl();
this.debugMetricsCollection.modelAttrName = "data";
this.commonTableOptions = {
collection: this.debugMetricsCollection,
includeFilter: false,
includePagination: true,
includeFooterRecords: true,
includePageSize: true,
includeGotoPage: true,
includeAtlasTableSorting: true,
includeTableLoader: true,
includeColumnManager: false,
gridOpts: {
className: "table table-hover backgrid table-quickMenu",
emptyText: 'No records found!'
},
filterOpts: {},
paginatorOpts: {}
};
this.currPage = 1;
this.limit = 26;
},
bindEvents: function() {
var that = this;
},
onRender: function() {
this.bindEvents();
this.$('.debug-metrics-table').show();
this.fetchMetricData();
},
fetchMetricData: function(options) {
var that = this;
this.debugMetricsCollection.fetch({
success: function(data) {
var data = _.first(data.toJSON()),
metricsDataKeys = data ? Object.keys(data) : null;
that.debugMetricsCollection.fullCollection.reset();
_.each(metricsDataKeys.sort(), function(keyName) {
that.debugMetricsCollection.add(data[keyName]);
});
},
complete: function(data) {
that.renderTableLayoutView();
}
});
},
renderTableLayoutView: function() {
var that = this;
require(['utils/TableLayout'], function(TableLayout) {
var cols = new Backgrid.Columns(that.getAuditTableColumns());
that.RDebugMetricsTableLayoutView.show(new TableLayout(_.extend({}, that.commonTableOptions, {
columns: cols
})));
if (!(that.debugMetricsCollection.models.length < that.limit)) {
that.RDebugMetricsTableLayoutView.$el.find('table tr').last().hide();
}
});
},
getAuditTableColumns: function() {
var that = this;
return this.debugMetricsCollection.constructor.getTableCols({
name: {
label: "Name",
cell: "html",
sortable: true,
editable: false
},
numops: {
label: "Count",
cell: "html",
sortable: true,
editable: false
},
minTime: {
label: "Min Time (secs)",
cell: "html",
sortable: true,
editable: false,
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
return parseFloat((rawValue % 1000) / 100).toFixed(3);
}
})
},
maxTime: {
label: "Max Time (secs)",
cell: "html",
sortable: true,
editable: false,
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
return parseFloat((rawValue % 1000) / 100).toFixed(3);
}
})
},
avgTime: {
label: "Average Time (secs)",
cell: "html",
sortable: true,
editable: false,
formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
fromRaw: function(rawValue, model) {
return parseFloat((rawValue % 1000) / 100).toFixed(3);
}
})
}
}, this.debugMetricsCollection);
}
});
return DebugMetricsTableLayoutView;
});

View File

@ -34,12 +34,14 @@ define(['require',
templateHelpers: function() {
return {
apiDocUrl: UrlLinks.apiDocUrl(),
isDebugMetricsEnabled: Globals.isDebugMetricsEnabled
};
},
ui: {
backButton: "[data-id='backButton']",
menuHamburger: "[data-id='menuHamburger']",
administrator: "[data-id='administrator']",
showDebug: "[data-id='showDebug']",
signOut: "[data-id='signOut']",
uiSwitch: "[data-id='uiSwitch']"
},
@ -67,6 +69,14 @@ define(['require',
updateTabState: true
});
};
events['click ' + this.ui.showDebug] = function() {
Utils.setUrl({
url: "#!/debugMetrics",
mergeBrowserUrl: false,
trigger: true,
updateTabState: true
});
};
events["click " + this.ui.uiSwitch] = function() {
var path = Utils.getBaseUrl(window.location.pathname) + "/index.html";
if (window.location.hash.length > 2) {
@ -144,4 +154,4 @@ define(['require',
},
});
return Header;
});
});

View File

@ -0,0 +1,25 @@
#
# 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.
#
# syntax: [prefix].[source|sink].[instance].[options]
# See javadoc of package-info.java for org.apache.hadoop.metrics2 for details
# default sampling period, in seconds
*.period=30
atlas-debug-metrics-context.sink.atlas-debug-metrics-context.class=org.apache.hadoop.metrics2.sink.FileSink
atlas-debug-metrics-context.sink.atlas-debug-metrics-context.context=atlas-debug-metrics-context
atlas-debug-metrics-context.sink.atlas-debug-metrics-context.filename=${atlas.log.dir}/atlas-metrics.out

View File

@ -77,6 +77,7 @@ public enum AtlasConfiguration {
REBUILD_INDEX("atlas.rebuild.index", false),
STORE_DIFFERENTIAL_AUDITS("atlas.entity.audit.differential", false),
DSL_EXECUTOR_TRAVERSAL("atlas.dsl.executor.traversal", true),
DEBUG_METRICS_ENABLED("atlas.debug.metrics.enabled", false),
TASKS_USE_ENABLED("atlas.tasks.enabled", true);
private static final Configuration APPLICATION_PROPERTIES;

View File

@ -0,0 +1,82 @@
/*
* 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.
*/
package org.apache.atlas.web.model;
public class DebugMetrics {
private String name;
private int numops;
private float minTime;
private float maxTime;
private float stdDevTime;
private float avgTime;
public DebugMetrics() {}
public DebugMetrics(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNumops() {
return numops;
}
public void setNumops(int numops) {
this.numops = numops;
}
public float getMinTime() {
return minTime;
}
public void setMinTime(float minTime) {
this.minTime = minTime;
}
public float getMaxTime() {
return maxTime;
}
public void setMaxTime(float maxTime) {
this.maxTime = maxTime;
}
public float getStdDevTime() {
return stdDevTime;
}
public void setStdDevTime(float stdDevTime) {
this.stdDevTime = stdDevTime;
}
public float getAvgTime() {
return avgTime;
}
public void setAvgTime(float avgTime) {
this.avgTime = avgTime;
}
}

View File

@ -21,6 +21,7 @@ package org.apache.atlas.web.resources;
import com.sun.jersey.multipart.FormDataParam;
import org.apache.atlas.ApplicationProperties;
import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasConfiguration;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.authorize.AtlasAdminAccessRequest;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
@ -66,6 +67,7 @@ import org.apache.atlas.util.SearchTracker;
import org.apache.atlas.utils.AtlasJson;
import org.apache.atlas.utils.AtlasPerfTracer;
import org.apache.atlas.web.filters.AtlasCSRFPreventionFilter;
import org.apache.atlas.web.service.AtlasDebugMetricsSink;
import org.apache.atlas.web.service.ServiceState;
import org.apache.atlas.web.util.Servlets;
import org.apache.commons.collections.CollectionUtils;
@ -80,7 +82,6 @@ import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.http.HttpServletRequest;
@ -167,6 +168,8 @@ public class AdminResource {
private final EntityAuditRepository auditRepository;
private final boolean isTimezoneFormatEnabled;
private final String uiDateFormat;
private final AtlasDebugMetricsSink debugMetricsRESTSink;
private final boolean isDebugMetricsEnabled;
static {
try {
@ -183,7 +186,7 @@ public class AdminResource {
AtlasServerService serverService,
ExportImportAuditService exportImportAuditService, AtlasEntityStore entityStore,
AtlasPatchManager patchManager, AtlasAuditService auditService, EntityAuditRepository auditRepository,
TaskManagement taskManagement) {
TaskManagement taskManagement, AtlasDebugMetricsSink debugMetricsRESTSink) {
this.serviceState = serviceState;
this.metricsService = metricsService;
this.exportService = exportService;
@ -199,15 +202,18 @@ public class AdminResource {
this.auditService = auditService;
this.auditRepository = auditRepository;
this.taskManagement = taskManagement;
this.debugMetricsRESTSink = debugMetricsRESTSink;
if (atlasProperties != null) {
this.defaultUIVersion = atlasProperties.getString(DEFAULT_UI_VERSION, UI_VERSION_V2);
this.isTimezoneFormatEnabled = atlasProperties.getBoolean(UI_DATE_TIMEZONE_FORMAT_ENABLED, true);
this.uiDateFormat = atlasProperties.getString(UI_DATE_FORMAT, UI_DATE_DEFAULT_FORMAT);
this.isDebugMetricsEnabled = AtlasConfiguration.DEBUG_METRICS_ENABLED.getBoolean();
} else {
this.defaultUIVersion = UI_VERSION_V2;
this.isTimezoneFormatEnabled = true;
this.uiDateFormat = UI_DATE_DEFAULT_FORMAT;
this.isDebugMetricsEnabled = false;
}
}
@ -355,6 +361,7 @@ public class AdminResource {
responseData.put("timezones", TIMEZONE_LIST);
responseData.put(UI_DATE_TIMEZONE_FORMAT_ENABLED, isTimezoneFormatEnabled);
responseData.put(UI_DATE_FORMAT, uiDateFormat);
responseData.put(AtlasConfiguration.DEBUG_METRICS_ENABLED.getPropertyName(), isDebugMetricsEnabled);
response = Response.ok(AtlasJson.toV1Json(responseData)).build();
@ -759,6 +766,12 @@ public class AdminResource {
}
}
@GET
@Path("/debug/metrics")
public Map getDebugMetrics() {
return debugMetricsRESTSink.getMetrics();
}
private String getEditableEntityTypes(Configuration config) {
String ret = DEFAULT_EDITABLE_ENTITY_TYPES;

View File

@ -20,6 +20,7 @@ package org.apache.atlas.web.rest;
import org.apache.atlas.AtlasClient;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.SortOrder;
import org.apache.atlas.annotation.Timed;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.discovery.AtlasDiscoveryService;
import org.apache.atlas.discovery.EntityDiscoveryService;
@ -100,6 +101,7 @@ public class DiscoveryREST {
*/
@GET
@Path("/dsl")
@Timed
public AtlasSearchResult searchUsingDSL(@QueryParam("query") String query,
@QueryParam("typeName") String typeName,
@QueryParam("classification") String classification,
@ -147,6 +149,7 @@ public class DiscoveryREST {
*/
@GET
@Path("/fulltext")
@Timed
public AtlasSearchResult searchUsingFullText(@QueryParam("query") String query,
@QueryParam("excludeDeletedEntities") boolean excludeDeletedEntities,
@QueryParam("limit") int limit,
@ -186,6 +189,7 @@ public class DiscoveryREST {
*/
@GET
@Path("/basic")
@Timed
public AtlasSearchResult searchUsingBasic(@QueryParam("query") String query,
@QueryParam("typeName") String typeName,
@QueryParam("classification") String classification,
@ -241,6 +245,7 @@ public class DiscoveryREST {
*/
@GET
@Path("/attribute")
@Timed
public AtlasSearchResult searchUsingAttribute(@QueryParam("attrName") String attrName,
@QueryParam("attrValuePrefix") String attrValuePrefix,
@QueryParam("typeName") String typeName,
@ -314,6 +319,7 @@ public class DiscoveryREST {
*/
@Path("basic")
@POST
@Timed
public AtlasSearchResult searchWithParameters(SearchParameters parameters) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -364,6 +370,7 @@ public class DiscoveryREST {
*/
@GET
@Path("relationship")
@Timed
public AtlasSearchResult searchRelatedEntities(@QueryParam("guid") String guid,
@QueryParam("relation") String relation,
@QueryParam("attributes") Set<String> attributes,
@ -409,6 +416,7 @@ public class DiscoveryREST {
*/
@POST
@Path("saved")
@Timed
public AtlasUserSavedSearch addSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException, IOException {
validateUserSavedSearch(savedSearch);
@ -433,6 +441,7 @@ public class DiscoveryREST {
*/
@PUT
@Path("saved")
@Timed
public AtlasUserSavedSearch updateSavedSearch(AtlasUserSavedSearch savedSearch) throws AtlasBaseException {
validateUserSavedSearch(savedSearch);
@ -458,6 +467,7 @@ public class DiscoveryREST {
*/
@GET
@Path("saved/{name}")
@Timed
public AtlasUserSavedSearch getSavedSearch(@PathParam("name") String searchName,
@QueryParam("user") String userName) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", searchName);
@ -484,6 +494,7 @@ public class DiscoveryREST {
*/
@GET
@Path("saved")
@Timed
public List<AtlasUserSavedSearch> getSavedSearches(@QueryParam("user") String userName) throws AtlasBaseException {
Servlets.validateQueryParamLength("user", userName);
@ -505,6 +516,7 @@ public class DiscoveryREST {
*/
@DELETE
@Path("saved/{guid}")
@Timed
public void deleteSavedSearch(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -532,6 +544,7 @@ public class DiscoveryREST {
*/
@Path("saved/execute/{name}")
@GET
@Timed
public AtlasSearchResult executeSavedSearchByName(@PathParam("name") String searchName,
@QueryParam("user") String userName) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", searchName);
@ -562,6 +575,7 @@ public class DiscoveryREST {
*/
@Path("saved/execute/guid/{guid}")
@GET
@Timed
public AtlasSearchResult executeSavedSearchByGuid(@PathParam("guid") String searchGuid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", searchGuid);
@ -589,6 +603,7 @@ public class DiscoveryREST {
*/
@Path("/quick")
@GET
@Timed
public AtlasQuickSearchResult quickSearch(@QueryParam("query") String query,
@QueryParam("typeName") String typeName,
@QueryParam("excludeDeletedEntities") boolean excludeDeletedEntities,
@ -633,6 +648,7 @@ public class DiscoveryREST {
*/
@Path("/quick")
@POST
@Timed
public AtlasQuickSearchResult quickSearch(QuickSearchParameters quickSearchParameters) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -665,6 +681,7 @@ public class DiscoveryREST {
@Path("suggestions")
@GET
@Timed
public AtlasSuggestionsResult getSuggestions(@QueryParam("prefixString") String prefixString, @QueryParam("fieldName") String fieldName) {
AtlasPerfTracer perf = null;

View File

@ -21,6 +21,7 @@ import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.EntityAuditEvent;
import org.apache.atlas.annotation.Timed;
import org.apache.atlas.authorize.AtlasAuthorizationUtils;
import org.apache.atlas.authorize.AtlasEntityAccessRequest;
import org.apache.atlas.authorize.AtlasPrivilege;
@ -123,6 +124,7 @@ public class EntityREST {
*/
@GET
@Path("/guid/{guid}")
@Timed
public AtlasEntityWithExtInfo getById(@PathParam("guid") String guid, @QueryParam("minExtInfo") @DefaultValue("false") boolean minExtInfo, @QueryParam("ignoreRelationships") @DefaultValue("false") boolean ignoreRelationships) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -147,6 +149,7 @@ public class EntityREST {
*/
@GET
@Path("/guid/{guid}/header")
@Timed
public AtlasEntityHeader getHeaderById(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -182,6 +185,7 @@ public class EntityREST {
*/
@GET
@Path("/uniqueAttribute/type/{typeName}/header")
@Timed
public AtlasEntityHeader getEntityHeaderByUniqueAttributes(@PathParam("typeName") String typeName,
@Context HttpServletRequest servletRequest) throws AtlasBaseException {
Servlets.validateQueryParamLength("typeName", typeName);
@ -225,6 +229,7 @@ public class EntityREST {
*/
@GET
@Path("/uniqueAttribute/type/{typeName}")
@Timed
public AtlasEntityWithExtInfo getByUniqueAttributes(@PathParam("typeName") String typeName, @QueryParam("minExtInfo") @DefaultValue("false") boolean minExtInfo,
@QueryParam("ignoreRelationships") @DefaultValue("false") boolean ignoreRelationships, @Context HttpServletRequest servletRequest) throws AtlasBaseException {
Servlets.validateQueryParamLength("typeName", typeName);
@ -267,6 +272,7 @@ public class EntityREST {
*******/
@PUT
@Path("/uniqueAttribute/type/{typeName}")
@Timed
public EntityMutationResponse partialUpdateEntityByUniqueAttrs(@PathParam("typeName") String typeName,
@Context HttpServletRequest servletRequest,
AtlasEntityWithExtInfo entityInfo) throws Exception {
@ -310,6 +316,7 @@ public class EntityREST {
*/
@DELETE
@Path("/uniqueAttribute/type/{typeName}")
@Timed
public EntityMutationResponse deleteByUniqueAttribute(@PathParam("typeName") String typeName,
@Context HttpServletRequest servletRequest) throws AtlasBaseException {
Servlets.validateQueryParamLength("typeName", typeName);
@ -339,6 +346,7 @@ public class EntityREST {
* @throws AtlasBaseException
*/
@POST
@Timed
public EntityMutationResponse createOrUpdate(AtlasEntityWithExtInfo entity) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -361,6 +369,7 @@ public class EntityREST {
*******/
@PUT
@Path("/guid/{guid}")
@Timed
public EntityMutationResponse partialUpdateEntityAttrByGuid(@PathParam("guid") String guid,
@QueryParam("name") String attrName,
Object attrValue) throws Exception {
@ -387,6 +396,7 @@ public class EntityREST {
*/
@DELETE
@Path("/guid/{guid}")
@Timed
public EntityMutationResponse deleteByGuid(@PathParam("guid") final String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -410,6 +420,7 @@ public class EntityREST {
*/
@GET
@Path("/guid/{guid}/classification/{classificationName}")
@Timed
public AtlasClassification getClassification(@PathParam("guid") String guid, @PathParam("classificationName") final String classificationName) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
Servlets.validateQueryParamLength("classificationName", classificationName);
@ -439,6 +450,7 @@ public class EntityREST {
*/
@GET
@Path("/guid/{guid}/classifications")
@Timed
public AtlasClassification.AtlasClassifications getClassifications(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -465,6 +477,7 @@ public class EntityREST {
*/
@POST
@Path("/uniqueAttribute/type/{typeName}/classifications")
@Timed
public void addClassificationsByUniqueAttribute(@PathParam("typeName") String typeName, @Context HttpServletRequest servletRequest, List<AtlasClassification> classifications) throws AtlasBaseException {
Servlets.validateQueryParamLength("typeName", typeName);
@ -495,6 +508,7 @@ public class EntityREST {
*/
@POST
@Path("/guid/{guid}/classifications")
@Timed
public void addClassifications(@PathParam("guid") final String guid, List<AtlasClassification> classifications) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -521,6 +535,7 @@ public class EntityREST {
*/
@PUT
@Path("/uniqueAttribute/type/{typeName}/classifications")
@Timed
public void updateClassificationsByUniqueAttribute(@PathParam("typeName") String typeName, @Context HttpServletRequest servletRequest, List<AtlasClassification> classifications) throws AtlasBaseException {
Servlets.validateQueryParamLength("typeName", typeName);
@ -552,6 +567,7 @@ public class EntityREST {
*/
@PUT
@Path("/guid/{guid}/classifications")
@Timed
public void updateClassifications(@PathParam("guid") final String guid, List<AtlasClassification> classifications) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -580,6 +596,7 @@ public class EntityREST {
*/
@DELETE
@Path("/uniqueAttribute/type/{typeName}/classification/{classificationName}")
@Timed
public void deleteClassificationByUniqueAttribute(@PathParam("typeName") String typeName, @Context HttpServletRequest servletRequest,@PathParam("classificationName") String classificationName) throws AtlasBaseException {
Servlets.validateQueryParamLength("typeName", typeName);
Servlets.validateQueryParamLength("classificationName", classificationName);
@ -612,6 +629,7 @@ public class EntityREST {
*/
@DELETE
@Path("/guid/{guid}/classification/{classificationName}")
@Timed
public void deleteClassification(@PathParam("guid") String guid,
@PathParam("classificationName") final String classificationName,
@QueryParam("associatedEntityGuid") final String associatedEntityGuid) throws AtlasBaseException {
@ -663,6 +681,7 @@ public class EntityREST {
*/
@GET
@Path("/bulk/uniqueAttribute/type/{typeName}")
@Timed
public AtlasEntitiesWithExtInfo getEntitiesByUniqueAttributes(@PathParam("typeName") String typeName,
@QueryParam("minExtInfo") @DefaultValue("false") boolean minExtInfo,
@QueryParam("ignoreRelationships") @DefaultValue("false") boolean ignoreRelationships,
@ -695,6 +714,7 @@ public class EntityREST {
*/
@GET
@Path("/bulk")
@Timed
public AtlasEntitiesWithExtInfo getByGuids(@QueryParam("guid") List<String> guids, @QueryParam("minExtInfo") @DefaultValue("false") boolean minExtInfo, @QueryParam("ignoreRelationships") @DefaultValue("false") boolean ignoreRelationships) throws AtlasBaseException {
if (CollectionUtils.isNotEmpty(guids)) {
for (String guid : guids) {
@ -725,6 +745,7 @@ public class EntityREST {
*/
@POST
@Path("/bulk")
@Timed
public EntityMutationResponse createOrUpdate(AtlasEntitiesWithExtInfo entities) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -747,6 +768,7 @@ public class EntityREST {
*/
@DELETE
@Path("/bulk")
@Timed
public EntityMutationResponse deleteByGuids(@QueryParam("guid") final List<String> guids) throws AtlasBaseException {
if (CollectionUtils.isNotEmpty(guids)) {
for (String guid : guids) {
@ -772,6 +794,7 @@ public class EntityREST {
*/
@POST
@Path("/bulk/classification")
@Timed
public void addClassification(ClassificationAssociateRequest request) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -799,6 +822,7 @@ public class EntityREST {
@GET
@Path("{guid}/audit")
@Timed
public List<EntityAuditEventV2> getAuditEvents(@PathParam("guid") String guid, @QueryParam("startKey") String startKey,
@QueryParam("auditAction") EntityAuditActionV2 auditAction,
@QueryParam("count") @DefaultValue("100") short count,
@ -854,6 +878,7 @@ public class EntityREST {
@GET
@Path("bulk/headers")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Timed
public AtlasEntityHeaders getEntityHeaders(@QueryParam("tagUpdateStartTime") long tagUpdateStartTime) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -879,6 +904,7 @@ public class EntityREST {
@Path("bulk/setClassifications")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Timed
public String setClassifications(AtlasEntityHeaders entityHeaders) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -898,6 +924,7 @@ public class EntityREST {
@Path("/guid/{guid}/businessmetadata")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Timed
public void addOrUpdateBusinessAttributes(@PathParam("guid") final String guid, @QueryParam("isOverwrite") @DefaultValue("false") boolean isOverwrite, Map<String, Map<String, Object>> businessAttributes) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -916,6 +943,7 @@ public class EntityREST {
@Path("/guid/{guid}/businessmetadata")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Timed
public void removeBusinessAttributes(@PathParam("guid") final String guid, Map<String, Map<String, Object>> businessAttributes) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -934,6 +962,7 @@ public class EntityREST {
@Path("/guid/{guid}/businessmetadata/{bmName}")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Timed
public void addOrUpdateBusinessAttributes(@PathParam("guid") final String guid, @PathParam("bmName") final String bmName, Map<String, Object> businessAttributes) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -952,6 +981,7 @@ public class EntityREST {
@Path("/guid/{guid}/businessmetadata/{bmName}")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Timed
public void removeBusinessAttributes(@PathParam("guid") final String guid, @PathParam("bmName") final String bmName, Map<String, Object> businessAttributes) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -976,6 +1006,7 @@ public class EntityREST {
@Path("/guid/{guid}/labels")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Timed
public void setLabels(@PathParam("guid") final String guid, Set<String> labels) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -999,6 +1030,7 @@ public class EntityREST {
@Path("/guid/{guid}/labels")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Timed
public void removeLabels(@PathParam("guid") final String guid, Set<String> labels) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -1022,6 +1054,7 @@ public class EntityREST {
@Path("/guid/{guid}/labels")
@Produces(Servlets.JSON_MEDIA_TYPE)
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Timed
public void addLabels(@PathParam("guid") final String guid, Set<String> labels) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -1038,6 +1071,7 @@ public class EntityREST {
@POST
@Path("/uniqueAttribute/type/{typeName}/labels")
@Timed
public void setLabels(@PathParam("typeName") String typeName, Set<String> labels,
@Context HttpServletRequest servletRequest) throws AtlasBaseException {
@ -1065,6 +1099,7 @@ public class EntityREST {
@PUT
@Path("/uniqueAttribute/type/{typeName}/labels")
@Timed
public void addLabels(@PathParam("typeName") String typeName, Set<String> labels,
@Context HttpServletRequest servletRequest) throws AtlasBaseException {
Servlets.validateQueryParamLength("typeName", typeName);
@ -1091,6 +1126,7 @@ public class EntityREST {
@DELETE
@Path("/uniqueAttribute/type/{typeName}/labels")
@Timed
public void removeLabels(@PathParam("typeName") String typeName, Set<String> labels,
@Context HttpServletRequest servletRequest) throws AtlasBaseException {
@ -1245,6 +1281,7 @@ public class EntityREST {
@POST
@Path("/businessmetadata/import")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Timed
public BulkImportResponse importBMAttributes(@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail) throws AtlasBaseException {

View File

@ -21,6 +21,7 @@ import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.SortOrder;
import org.apache.atlas.annotation.Timed;
import org.apache.atlas.bulkimport.BulkImportResponse;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.glossary.GlossaryService;
@ -85,6 +86,7 @@ public class GlossaryREST {
* @throws AtlasBaseException
*/
@GET
@Timed
public List<AtlasGlossary> getGlossaries(@DefaultValue("-1") @QueryParam("limit") final String limit,
@DefaultValue("0") @QueryParam("offset") final String offset,
@DefaultValue("ASC") @QueryParam("sort") final String sort) throws AtlasBaseException {
@ -112,6 +114,7 @@ public class GlossaryREST {
*/
@GET
@Path("/{glossaryGuid}")
@Timed
public AtlasGlossary getGlossary(@PathParam("glossaryGuid") String glossaryGuid) throws AtlasBaseException {
Servlets.validateQueryParamLength("glossaryGuid", glossaryGuid);
@ -143,6 +146,7 @@ public class GlossaryREST {
*/
@GET
@Path("/{glossaryGuid}/detailed")
@Timed
public AtlasGlossary.AtlasGlossaryExtInfo getDetailedGlossary(@PathParam("glossaryGuid") String glossaryGuid) throws AtlasBaseException {
Servlets.validateQueryParamLength("glossaryGuid", glossaryGuid);
@ -174,6 +178,7 @@ public class GlossaryREST {
*/
@GET
@Path("/term/{termGuid}")
@Timed
public AtlasGlossaryTerm getGlossaryTerm(@PathParam("termGuid") String termGuid) throws AtlasBaseException {
Servlets.validateQueryParamLength("termGuid", termGuid);
@ -204,6 +209,7 @@ public class GlossaryREST {
*/
@GET
@Path("/category/{categoryGuid}")
@Timed
public AtlasGlossaryCategory getGlossaryCategory(@PathParam("categoryGuid") String categoryGuid) throws AtlasBaseException {
Servlets.validateQueryParamLength("categoryGuid", categoryGuid);
AtlasPerfTracer perf = null;
@ -234,6 +240,7 @@ public class GlossaryREST {
* @HTTP 409 If Glossary definition already exists (duplicate qualifiedName)
*/
@POST
@Timed
public AtlasGlossary createGlossary(AtlasGlossary atlasGlossary) throws AtlasBaseException {
AtlasPerfTracer perf = null;
try {
@ -258,6 +265,7 @@ public class GlossaryREST {
*/
@POST
@Path("/term")
@Timed
public AtlasGlossaryTerm createGlossaryTerm(AtlasGlossaryTerm glossaryTerm) throws AtlasBaseException {
AtlasPerfTracer perf = null;
try {
@ -283,6 +291,7 @@ public class GlossaryREST {
*/
@POST
@Path("/terms")
@Timed
public List<AtlasGlossaryTerm> createGlossaryTerms(List<AtlasGlossaryTerm> glossaryTerm) throws AtlasBaseException {
AtlasPerfTracer perf = null;
try {
@ -312,6 +321,7 @@ public class GlossaryREST {
*/
@POST
@Path("/category")
@Timed
public AtlasGlossaryCategory createGlossaryCategory(AtlasGlossaryCategory glossaryCategory) throws AtlasBaseException {
AtlasPerfTracer perf = null;
try {
@ -337,6 +347,7 @@ public class GlossaryREST {
*/
@POST
@Path("/categories")
@Timed
public List<AtlasGlossaryCategory> createGlossaryCategories(List<AtlasGlossaryCategory> glossaryCategory) throws AtlasBaseException {
AtlasPerfTracer perf = null;
try {
@ -367,6 +378,7 @@ public class GlossaryREST {
*/
@PUT
@Path("/{glossaryGuid}")
@Timed
public AtlasGlossary updateGlossary(@PathParam("glossaryGuid") String glossaryGuid, AtlasGlossary updatedGlossary) throws AtlasBaseException {
Servlets.validateQueryParamLength("glossaryGuid", glossaryGuid);
AtlasPerfTracer perf = null;
@ -393,6 +405,7 @@ public class GlossaryREST {
*/
@PUT
@Path("/{glossaryGuid}/partial")
@Timed
public AtlasGlossary partialUpdateGlossary(@PathParam("glossaryGuid") String glossaryGuid, Map<String, String> partialUpdates) throws AtlasBaseException {
Servlets.validateQueryParamLength("glossaryGuid", glossaryGuid);
@ -432,6 +445,7 @@ public class GlossaryREST {
*/
@PUT
@Path("/term/{termGuid}")
@Timed
public AtlasGlossaryTerm updateGlossaryTerm(@PathParam("termGuid") String termGuid, AtlasGlossaryTerm glossaryTerm) throws AtlasBaseException {
Servlets.validateQueryParamLength("termGuid", termGuid);
AtlasPerfTracer perf = null;
@ -458,6 +472,7 @@ public class GlossaryREST {
*/
@PUT
@Path("/term/{termGuid}/partial")
@Timed
public AtlasGlossaryTerm partialUpdateGlossaryTerm(@PathParam("termGuid") String termGuid, Map<String, String> partialUpdates) throws AtlasBaseException {
Servlets.validateQueryParamLength("termGuid", termGuid);
@ -497,6 +512,7 @@ public class GlossaryREST {
*/
@PUT
@Path("/category/{categoryGuid}")
@Timed
public AtlasGlossaryCategory updateGlossaryCategory(@PathParam("categoryGuid") String categoryGuid, AtlasGlossaryCategory glossaryCategory) throws AtlasBaseException {
Servlets.validateQueryParamLength("categoryGuid", categoryGuid);
AtlasPerfTracer perf = null;
@ -523,6 +539,7 @@ public class GlossaryREST {
*/
@PUT
@Path("/category/{categoryGuid}/partial")
@Timed
public AtlasGlossaryCategory partialUpdateGlossaryCategory(@PathParam("categoryGuid") String categoryGuid, Map<String, String> partialUpdates) throws AtlasBaseException {
Servlets.validateQueryParamLength("categoryGuid", categoryGuid);
@ -559,6 +576,7 @@ public class GlossaryREST {
*/
@DELETE
@Path("/{glossaryGuid}")
@Timed
public void deleteGlossary(@PathParam("glossaryGuid") String glossaryGuid) throws AtlasBaseException {
Servlets.validateQueryParamLength("glossaryGuid", glossaryGuid);
AtlasPerfTracer perf = null;
@ -581,6 +599,7 @@ public class GlossaryREST {
*/
@DELETE
@Path("/term/{termGuid}")
@Timed
public void deleteGlossaryTerm(@PathParam("termGuid") String termGuid) throws AtlasBaseException {
Servlets.validateQueryParamLength("termGuid", termGuid);
AtlasPerfTracer perf = null;
@ -603,6 +622,7 @@ public class GlossaryREST {
*/
@DELETE
@Path("/category/{categoryGuid}")
@Timed
public void deleteGlossaryCategory(@PathParam("categoryGuid") String categoryGuid) throws AtlasBaseException {
Servlets.validateQueryParamLength("categoryGuid", categoryGuid);
AtlasPerfTracer perf = null;
@ -629,6 +649,7 @@ public class GlossaryREST {
*/
@GET
@Path("/{glossaryGuid}/terms")
@Timed
public List<AtlasGlossaryTerm> getGlossaryTerms(@PathParam("glossaryGuid") String glossaryGuid,
@DefaultValue("-1") @QueryParam("limit") String limit,
@DefaultValue("0") @QueryParam("offset") String offset,
@ -660,6 +681,7 @@ public class GlossaryREST {
*/
@GET
@Path("/{glossaryGuid}/terms/headers")
@Timed
public List<AtlasRelatedTermHeader> getGlossaryTermHeaders(@PathParam("glossaryGuid") String glossaryGuid,
@DefaultValue("-1") @QueryParam("limit") String limit,
@DefaultValue("0") @QueryParam("offset") String offset,
@ -691,6 +713,7 @@ public class GlossaryREST {
*/
@GET
@Path("/{glossaryGuid}/categories")
@Timed
public List<AtlasGlossaryCategory> getGlossaryCategories(@PathParam("glossaryGuid") String glossaryGuid,
@DefaultValue("-1") @QueryParam("limit") String limit,
@DefaultValue("0") @QueryParam("offset") String offset,
@ -722,6 +745,7 @@ public class GlossaryREST {
*/
@GET
@Path("/{glossaryGuid}/categories/headers")
@Timed
public List<AtlasRelatedCategoryHeader> getGlossaryCategoriesHeaders(@PathParam("glossaryGuid") String glossaryGuid,
@DefaultValue("-1") @QueryParam("limit") String limit,
@DefaultValue("0") @QueryParam("offset") String offset,
@ -753,6 +777,7 @@ public class GlossaryREST {
*/
@GET
@Path("/category/{categoryGuid}/terms")
@Timed
public List<AtlasRelatedTermHeader> getCategoryTerms(@PathParam("categoryGuid") String categoryGuid,
@DefaultValue("-1") @QueryParam("limit") String limit,
@DefaultValue("0") @QueryParam("offset") String offset,
@ -785,6 +810,7 @@ public class GlossaryREST {
*/
@GET
@Path("/terms/{termGuid}/related")
@Timed
public Map<AtlasGlossaryTerm.Relation, Set<AtlasRelatedTermHeader>> getRelatedTerms(@PathParam("termGuid") String termGuid,
@DefaultValue("-1") @QueryParam("limit") String limit,
@DefaultValue("0") @QueryParam("offset") String offset,
@ -817,6 +843,7 @@ public class GlossaryREST {
*/
@GET
@Path("/terms/{termGuid}/assignedEntities")
@Timed
public List<AtlasRelatedObjectId> getEntitiesAssignedWithTerm(@PathParam("termGuid") String termGuid,
@DefaultValue("-1") @QueryParam("limit") String limit,
@DefaultValue("0") @QueryParam("offset") String offset,
@ -848,6 +875,7 @@ public class GlossaryREST {
*/
@POST
@Path("/terms/{termGuid}/assignedEntities")
@Timed
public void assignTermToEntities(@PathParam("termGuid") String termGuid, List<AtlasRelatedObjectId> relatedObjectIds) throws AtlasBaseException {
Servlets.validateQueryParamLength("termGuid", termGuid);
@ -874,6 +902,7 @@ public class GlossaryREST {
*/
@DELETE
@Path("/terms/{termGuid}/assignedEntities")
@Timed
public void removeTermAssignmentFromEntities(@PathParam("termGuid") String termGuid, List<AtlasRelatedObjectId> relatedObjectIds) throws AtlasBaseException {
removeTermFromGlossary(termGuid, relatedObjectIds);
}
@ -890,6 +919,7 @@ public class GlossaryREST {
*/
@PUT
@Path("/terms/{termGuid}/assignedEntities")
@Timed
public void disassociateTermAssignmentFromEntities(@PathParam("termGuid") String termGuid, List<AtlasRelatedObjectId> relatedObjectIds) throws AtlasBaseException {
removeTermFromGlossary(termGuid, relatedObjectIds);
}
@ -924,6 +954,7 @@ public class GlossaryREST {
*/
@GET
@Path("/category/{categoryGuid}/related")
@Timed
public Map<String, List<AtlasRelatedCategoryHeader>> getRelatedCategories(@PathParam("categoryGuid") String categoryGuid,
@DefaultValue("-1") @QueryParam("limit") String limit,
@DefaultValue("0") @QueryParam("offset") String offset,
@ -984,6 +1015,7 @@ public class GlossaryREST {
@POST
@Path("/import")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Timed
public BulkImportResponse importGlossaryData(@FormDataParam("file") InputStream inputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail) throws AtlasBaseException {
return glossaryService.importGlossaryData(inputStream, fileDetail.getFileName());

View File

@ -20,6 +20,7 @@ package org.apache.atlas.web.rest;
import org.apache.atlas.AtlasErrorCode;
import org.apache.atlas.annotation.Timed;
import org.apache.atlas.discovery.AtlasLineageService;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
@ -30,7 +31,6 @@ import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.utils.AtlasPerfTracer;
import org.apache.atlas.web.util.Servlets;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
@ -89,6 +89,7 @@ public class LineageREST {
*/
@GET
@Path("/{guid}")
@Timed
public AtlasLineageInfo getLineageGraph(@PathParam("guid") String guid,
@QueryParam("direction") @DefaultValue(DEFAULT_DIRECTION) LineageDirection direction,
@QueryParam("depth") @DefaultValue(DEFAULT_DEPTH) int depth) throws AtlasBaseException {
@ -130,6 +131,7 @@ public class LineageREST {
@Path("/uniqueAttribute/type/{typeName}")
@Consumes(Servlets.JSON_MEDIA_TYPE)
@Produces(Servlets.JSON_MEDIA_TYPE)
@Timed
public AtlasLineageInfo getLineageByUniqueAttribute(@PathParam("typeName") String typeName, @QueryParam("direction") @DefaultValue(DEFAULT_DIRECTION) LineageDirection direction,
@QueryParam("depth") @DefaultValue(DEFAULT_DEPTH) int depth, @Context HttpServletRequest servletRequest) throws AtlasBaseException {
Servlets.validateQueryParamLength("typeName", typeName);

View File

@ -18,6 +18,7 @@
package org.apache.atlas.web.rest;
import org.apache.atlas.annotation.Timed;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.instance.AtlasRelationship;
import org.apache.atlas.model.instance.AtlasRelationship.AtlasRelationshipWithExtInfo;
@ -54,6 +55,7 @@ public class RelationshipREST {
* Create a new relationship between entities.
*/
@POST
@Timed
public AtlasRelationship create(AtlasRelationship relationship) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -73,6 +75,7 @@ public class RelationshipREST {
* Update an existing relationship between entities.
*/
@PUT
@Timed
public AtlasRelationship update(AtlasRelationship relationship) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -93,6 +96,7 @@ public class RelationshipREST {
*/
@GET
@Path("/guid/{guid}")
@Timed
public AtlasRelationshipWithExtInfo getById(@PathParam("guid") String guid,
@QueryParam("extendedInfo") @DefaultValue("false") boolean extendedInfo)
throws AtlasBaseException {
@ -124,6 +128,7 @@ public class RelationshipREST {
*/
@DELETE
@Path("/guid/{guid}")
@Timed
public void deleteById(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);

View File

@ -17,6 +17,7 @@
*/
package org.apache.atlas.web.rest;
import org.apache.atlas.annotation.Timed;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.SearchFilter;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
@ -81,6 +82,7 @@ public class TypesREST {
*/
@GET
@Path("/typedef/name/{name}")
@Timed
public AtlasBaseTypeDef getTypeDefByName(@PathParam("name") String name) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", name);
@ -98,6 +100,7 @@ public class TypesREST {
*/
@GET
@Path("/typedef/guid/{guid}")
@Timed
public AtlasBaseTypeDef getTypeDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -115,6 +118,7 @@ public class TypesREST {
*/
@GET
@Path("/typedefs/headers")
@Timed
public List<AtlasTypeDefHeader> getTypeDefHeaders(@Context HttpServletRequest httpServletRequest) throws AtlasBaseException {
SearchFilter searchFilter = getSearchFilter(httpServletRequest);
@ -131,6 +135,7 @@ public class TypesREST {
*/
@GET
@Path("/typedefs")
@Timed
public AtlasTypesDef getAllTypeDefs(@Context HttpServletRequest httpServletRequest) throws AtlasBaseException {
SearchFilter searchFilter = getSearchFilter(httpServletRequest);
@ -149,6 +154,7 @@ public class TypesREST {
*/
@GET
@Path("/enumdef/name/{name}")
@Timed
public AtlasEnumDef getEnumDefByName(@PathParam("name") String name) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", name);
@ -167,6 +173,7 @@ public class TypesREST {
*/
@GET
@Path("/enumdef/guid/{guid}")
@Timed
public AtlasEnumDef getEnumDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -186,6 +193,7 @@ public class TypesREST {
*/
@GET
@Path("/structdef/name/{name}")
@Timed
public AtlasStructDef getStructDefByName(@PathParam("name") String name) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", name);
@ -204,6 +212,7 @@ public class TypesREST {
*/
@GET
@Path("/structdef/guid/{guid}")
@Timed
public AtlasStructDef getStructDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -222,6 +231,7 @@ public class TypesREST {
*/
@GET
@Path("/classificationdef/name/{name}")
@Timed
public AtlasClassificationDef getClassificationDefByName(@PathParam("name") String name) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", name);
@ -240,6 +250,7 @@ public class TypesREST {
*/
@GET
@Path("/classificationdef/guid/{guid}")
@Timed
public AtlasClassificationDef getClassificationDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -258,6 +269,7 @@ public class TypesREST {
*/
@GET
@Path("/entitydef/name/{name}")
@Timed
public AtlasEntityDef getEntityDefByName(@PathParam("name") String name) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", name);
@ -276,6 +288,7 @@ public class TypesREST {
*/
@GET
@Path("/entitydef/guid/{guid}")
@Timed
public AtlasEntityDef getEntityDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -293,6 +306,7 @@ public class TypesREST {
*/
@GET
@Path("/relationshipdef/name/{name}")
@Timed
public AtlasRelationshipDef getRelationshipDefByName(@PathParam("name") String name) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", name);
@ -311,6 +325,7 @@ public class TypesREST {
*/
@GET
@Path("/relationshipdef/guid/{guid}")
@Timed
public AtlasRelationshipDef getRelationshipDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -329,6 +344,7 @@ public class TypesREST {
*/
@GET
@Path("/businessmetadatadef/guid/{guid}")
@Timed
public AtlasBusinessMetadataDef getBusinessMetadataDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
Servlets.validateQueryParamLength("guid", guid);
@ -347,6 +363,7 @@ public class TypesREST {
*/
@GET
@Path("/businessmetadatadef/name/{name}")
@Timed
public AtlasBusinessMetadataDef getBusinessMetadataDefByName(@PathParam("name") String name) throws AtlasBaseException {
Servlets.validateQueryParamLength("name", name);
@ -369,6 +386,7 @@ public class TypesREST {
*/
@POST
@Path("/typedefs")
@Timed
public AtlasTypesDef createAtlasTypeDefs(final AtlasTypesDef typesDef) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -395,6 +413,7 @@ public class TypesREST {
@PUT
@Path("/typedefs")
@Experimental
@Timed
public AtlasTypesDef updateAtlasTypeDefs(final AtlasTypesDef typesDef) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -420,6 +439,7 @@ public class TypesREST {
@DELETE
@Path("/typedefs")
@Experimental
@Timed
public void deleteAtlasTypeDefs(final AtlasTypesDef typesDef) throws AtlasBaseException {
AtlasPerfTracer perf = null;
@ -446,6 +466,7 @@ public class TypesREST {
*/
@DELETE
@Path("/typedef/name/{typeName}")
@Timed
public void deleteAtlasTypeByName(@PathParam("typeName") final String typeName) throws AtlasBaseException {
AtlasPerfTracer perf = null;

View File

@ -0,0 +1,115 @@
/**
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.
*/
package org.apache.atlas.web.service;
import org.apache.atlas.web.model.DebugMetrics;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.metrics2.AbstractMetric;
import org.apache.hadoop.metrics2.MetricsRecord;
import org.apache.hadoop.metrics2.MetricsSink;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import static org.apache.atlas.web.service.DebugMetricsWrapper.Constants.AVG_TIME;
import static org.apache.atlas.web.service.DebugMetricsWrapper.Constants.DEBUG_METRICS_SOURCE;
import static org.apache.atlas.web.service.DebugMetricsWrapper.Constants.MAX_TIME;
import static org.apache.atlas.web.service.DebugMetricsWrapper.Constants.MIN_TIME;
import static org.apache.atlas.web.service.DebugMetricsWrapper.Constants.NUM_OPS;
import static org.apache.atlas.web.service.DebugMetricsWrapper.Constants.STD_DEV_TIME;
@Component
public class AtlasDebugMetricsSink implements MetricsSink {
private final HashMap<String, DebugMetrics> metricStructuredSnapshot = new HashMap<>();
@Override
public void putMetrics(MetricsRecord metricsRecord) {
if (!DEBUG_METRICS_SOURCE.equals(metricsRecord.name())) {
return;
}
for (AbstractMetric metric : metricsRecord.metrics()) {
float value = metric.value().floatValue();
if (value == 0 || value == Float.MAX_VALUE || value == Float.MIN_VALUE) {
continue;
}
setMetricsData(metric);
}
}
public HashMap getMetrics() {
return metricStructuredSnapshot;
}
@Override
public void init(org.apache.commons.configuration2.SubsetConfiguration subsetConfiguration) {
}
@Override
public void flush() {
}
private void setMetricsData(AbstractMetric metric) {
String name = metric.name().toLowerCase();
String fieldCaps = AtlasDebugMetricsSource.fieldLowerCaseUpperCaseMap.get(name);
if (!StringUtils.isEmpty(fieldCaps)) {
String fieldNameLower = fieldCaps.toLowerCase();
String metricType = inferMeasureType(name, fieldNameLower);
DebugMetrics debugMetrics = metricStructuredSnapshot.get(fieldCaps);
if (debugMetrics == null) {
debugMetrics = new DebugMetrics(fieldCaps);
metricStructuredSnapshot.put(fieldCaps, debugMetrics);
}
updateMetricType(debugMetrics, metricType, metric);
}
}
private void updateMetricType(DebugMetrics debugMetrics, String metricType, AbstractMetric metric) {
switch (metricType) {
case NUM_OPS:
debugMetrics.setNumops(metric.value().intValue());
break;
case MIN_TIME:
debugMetrics.setMinTime(metric.value().floatValue());
break;
case MAX_TIME:
debugMetrics.setMaxTime(metric.value().floatValue());
break;
case STD_DEV_TIME:
debugMetrics.setStdDevTime(metric.value().floatValue());
break;
case AVG_TIME:
debugMetrics.setAvgTime(metric.value().floatValue());
break;
}
}
private static String inferMeasureType(String fullName, String nameWithoutMetricType) {
return fullName.replaceFirst(nameWithoutMetricType, "");
}
}

View File

@ -0,0 +1,647 @@
/*
* 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.
*/
package org.apache.atlas.web.service;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.metrics2.annotation.Metric;
import org.apache.hadoop.metrics2.annotation.Metrics;
import org.apache.hadoop.metrics2.lib.MutableRate;
import org.aspectj.lang.Signature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static org.apache.atlas.web.service.DebugMetricsWrapper.Constants.*;
@Metrics(context = DEBUG_METRICS_CONTEXT)
public class AtlasDebugMetricsSource {
private static final Logger LOG = LoggerFactory.getLogger(AtlasDebugMetricsSource.class);
protected @Metric(always = true) MutableRate entityREST_getById;
protected @Metric(always = true) MutableRate entityREST_createOrUpdate;
protected @Metric(always = true) MutableRate entityREST_deleteByGuid;
protected @Metric(always = true) MutableRate entityREST_getClassifications;
protected @Metric(always = true) MutableRate entityREST_addClassificationsByUniqAttr;
protected @Metric(always = true) MutableRate entityREST_addClassifications;
protected @Metric(always = true) MutableRate entityREST_deleteClassificationByUniqAttr;
protected @Metric(always = true) MutableRate entityREST_deleteClassification;
protected @Metric(always = true) MutableRate entityREST_getHeaderById;
protected @Metric(always = true) MutableRate entityREST_getEntityHeaderByUniqAttr;
protected @Metric(always = true) MutableRate entityREST_getByUniqueAttributes;
protected @Metric(always = true) MutableRate entityREST_partialUpdateEntityByUniqAttr;
protected @Metric(always = true) MutableRate entityREST_deleteByUniqAttr;
protected @Metric(always = true) MutableRate entityREST_updateClassificationsByUniqAttr;
protected @Metric(always = true) MutableRate entityREST_updateClassifications;
protected @Metric(always = true) MutableRate entityREST_getEntitiesByUniqAttr;
protected @Metric(always = true) MutableRate entityREST_getByGuids;
protected @Metric(always = true) MutableRate entityREST_createOrUpdateBulk;
protected @Metric(always = true) MutableRate entityREST_deleteByGuids;
protected @Metric(always = true) MutableRate entityREST_addClassification;
protected @Metric(always = true) MutableRate entityREST_getAuditEvents;
protected @Metric(always = true) MutableRate entityREST_getEntityHeaders;
protected @Metric(always = true) MutableRate entityREST_setClassifications;
protected @Metric(always = true) MutableRate entityREST_addOrUpdateBusinessAttributes;
protected @Metric(always = true) MutableRate entityREST_removeBusinessAttributes;
protected @Metric(always = true) MutableRate entityREST_addOrUpdateBusinessAttributesByName;
protected @Metric(always = true) MutableRate entityREST_removeBusinessAttributesByName;
protected @Metric(always = true) MutableRate entityREST_setLabels;
protected @Metric(always = true) MutableRate entityREST_addLabels;
protected @Metric(always = true) MutableRate entityREST_removeLabels;
protected @Metric(always = true) MutableRate entityREST_removeLabelsByTypeName;
protected @Metric(always = true) MutableRate entityREST_setLabelsByTypeName;
protected @Metric(always = true) MutableRate entityREST_addLabelsByTypeName;
protected @Metric(always = true) MutableRate entityREST_importBMAttributes;
protected @Metric(always = true) MutableRate typesREST_getEntityDefByName;
protected @Metric(always = true) MutableRate typesREST_getTypeDefByName;
protected @Metric(always = true) MutableRate typesREST_getTypeDefByGuid;
protected @Metric(always = true) MutableRate typesREST_getTypeDefHeaders;
protected @Metric(always = true) MutableRate typesREST_getAllTypeDefs;
protected @Metric(always = true) MutableRate typesREST_getEnumDefByName;
protected @Metric(always = true) MutableRate typesREST_getEnumDefByGuid;
protected @Metric(always = true) MutableRate typesREST_getStructDefByName;
protected @Metric(always = true) MutableRate typesREST_getStructDefByGuid;
protected @Metric(always = true) MutableRate typesREST_getClassificationDefByName;
protected @Metric(always = true) MutableRate typesREST_getClassificationDefByGuid;
protected @Metric(always = true) MutableRate typesREST_getEntityDefByGuid;
protected @Metric(always = true) MutableRate typesREST_getRelationshipDefByName;
protected @Metric(always = true) MutableRate typesREST_getRelationshipDefByGuid;
protected @Metric(always = true) MutableRate typesREST_getBusinessMetadataDefByGuid;
protected @Metric(always = true) MutableRate typesREST_getBusinessMetadataDefByName;
protected @Metric(always = true) MutableRate typesREST_createAtlasTypeDefs;
protected @Metric(always = true) MutableRate typesREST_updateAtlasTypeDefs;
protected @Metric(always = true) MutableRate typesREST_deleteAtlasTypeDefs;
protected @Metric(always = true) MutableRate typesREST_deleteAtlasTypeByName;
protected @Metric(always = true) MutableRate glossaryREST_getGlossaries;
protected @Metric(always = true) MutableRate glossaryREST_getGlossary;
protected @Metric(always = true) MutableRate glossaryREST_getDetailedGlossary;
protected @Metric(always = true) MutableRate glossaryREST_getGlossaryTerm;
protected @Metric(always = true) MutableRate glossaryREST_getGlossaryCategory;
protected @Metric(always = true) MutableRate glossaryREST_createGlossary;
protected @Metric(always = true) MutableRate glossaryREST_createGlossaryTerm;
protected @Metric(always = true) MutableRate glossaryREST_createGlossaryTerms;
protected @Metric(always = true) MutableRate glossaryREST_createGlossaryCategory;
protected @Metric(always = true) MutableRate glossaryREST_createGlossaryCategories;
protected @Metric(always = true) MutableRate glossaryREST_updateGlossary;
protected @Metric(always = true) MutableRate glossaryREST_partialUpdateGlossary;
protected @Metric(always = true) MutableRate glossaryREST_updateGlossaryTerm;
protected @Metric(always = true) MutableRate glossaryREST_partialUpdateGlossaryTerm;
protected @Metric(always = true) MutableRate glossaryREST_updateGlossaryCategory;
protected @Metric(always = true) MutableRate glossaryREST_partialUpdateGlossaryCategory;
protected @Metric(always = true) MutableRate glossaryREST_deleteGlossary;
protected @Metric(always = true) MutableRate glossaryREST_deleteGlossaryTerm;
protected @Metric(always = true) MutableRate glossaryREST_deleteGlossaryCategory;
protected @Metric(always = true) MutableRate glossaryREST_getGlossaryTerms;
protected @Metric(always = true) MutableRate glossaryREST_getGlossaryTermHeaders;
protected @Metric(always = true) MutableRate glossaryREST_getGlossaryCategories;
protected @Metric(always = true) MutableRate glossaryREST_getGlossaryCategoriesHeaders;
protected @Metric(always = true) MutableRate glossaryREST_getCategoryTerms;
protected @Metric(always = true) MutableRate glossaryREST_getRelatedTerms;
protected @Metric(always = true) MutableRate glossaryREST_getEntitiesAssignedWithTerm;
protected @Metric(always = true) MutableRate glossaryREST_assignTermToEntities;
protected @Metric(always = true) MutableRate glossaryREST_removeTermAssignmentFromEntities;
protected @Metric(always = true) MutableRate glossaryREST_disassociateTermAssignmentFromEntities;
protected @Metric(always = true) MutableRate glossaryREST_getRelatedCategories;
protected @Metric(always = true) MutableRate glossaryREST_importGlossaryData;
protected @Metric(always = true) MutableRate discoveryREST_quickSearchQuickSearchParams;
protected @Metric(always = true) MutableRate discoveryREST_searchUsingFullText;
protected @Metric(always = true) MutableRate discoveryREST_searchUsingAttribute;
protected @Metric(always = true) MutableRate discoveryREST_searchWithParameters;
protected @Metric(always = true) MutableRate discoveryREST_searchRelatedEntities;
protected @Metric(always = true) MutableRate discoveryREST_updateSavedSearch;
protected @Metric(always = true) MutableRate discoveryREST_getSavedSearch;
protected @Metric(always = true) MutableRate discoveryREST_getSavedSearches;
protected @Metric(always = true) MutableRate discoveryREST_deleteSavedSearch;
protected @Metric(always = true) MutableRate discoveryREST_executeSavedSearchByName;
protected @Metric(always = true) MutableRate discoveryREST_executeSavedSearchByGuid;
protected @Metric(always = true) MutableRate discoveryREST_getSuggestions;
protected @Metric(always = true) MutableRate discoveryREST_searchUsingDSL;
protected @Metric(always = true) MutableRate discoveryREST_searchUsingBasic;
protected @Metric(always = true) MutableRate discoveryREST_quickSearch;
protected @Metric(always = true) MutableRate discoveryREST_addSavedSearch;
protected @Metric(always = true) MutableRate notificationHookConsumer_doWork;
protected @Metric(always = true) MutableRate lineageREST_getLineageByUniqAttr;
protected @Metric(always = true) MutableRate lineageREST_getLineageGraph;
protected @Metric(always = true) MutableRate relationshipREST_create;
protected @Metric(always = true) MutableRate relationshipREST_update;
protected @Metric(always = true) MutableRate relationshipREST_getById;
protected @Metric(always = true) MutableRate relationshipREST_deleteById;
public static final Map<String, String> fieldLowerCaseUpperCaseMap = new HashMap<>();
public static final Set<String> debugMetricsAttributes = new HashSet<>();
public AtlasDebugMetricsSource() {
initAttrList();
populateFieldList();
}
public void update(Signature name, Long timeConsumed) {
String signatureName = name.toString();
switch (signatureName) {
case EntityREST_createOrUpdateBulk:
entityREST_createOrUpdateBulk.add(timeConsumed);
break;
case EntityREST_addOrUpdateBMByName:
entityREST_addOrUpdateBusinessAttributesByName.add(timeConsumed);
break;
case EntityREST_removeBMByName:
entityREST_removeBusinessAttributesByName.add(timeConsumed);
break;
case EntityREST_removeLabelsByTypeName:
entityREST_removeLabelsByTypeName.add(timeConsumed);
break;
case EntityREST_setLabelsByTypeName:
entityREST_setLabelsByTypeName.add(timeConsumed);
break;
case EntityREST_addLabelsByTypeName:
entityREST_addLabelsByTypeName.add(timeConsumed);
break;
case DiscoveryREST_quickSearchQuickSearchParams:
discoveryREST_quickSearchQuickSearchParams.add(timeConsumed);
break;
default:
update(name.toShortString(), timeConsumed);
break;
}
}
private void populateFieldList() {
Field fields[] = AtlasDebugMetricsSource.class.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getAnnotation(Metric.class) == null) {
continue;
}
String name = fields[i].getName();
for(String metricName : debugMetricsAttributes) {
fieldLowerCaseUpperCaseMap.put(name.toLowerCase() + metricName, StringUtils.capitalize(name));
}
}
}
private void initAttrList() {
debugMetricsAttributes.add(NUM_OPS);
debugMetricsAttributes.add(MIN_TIME);
debugMetricsAttributes.add(STD_DEV_TIME);
debugMetricsAttributes.add(MAX_TIME);
debugMetricsAttributes.add(AVG_TIME);
}
private void update(String name, Long timeConsumed) {
switch (name) {
case RelationshipREST_create:
relationshipREST_create.add(timeConsumed);
break;
case RelationshipREST_update:
relationshipREST_update.add(timeConsumed);
break;
case RelationshipREST_getById:
relationshipREST_getById.add(timeConsumed);
break;
case RelationshipREST_deleteById:
relationshipREST_deleteById.add(timeConsumed);
break;
//DiscoveryREST apis
case DiscoveryREST_searchUsingFullText:
discoveryREST_searchUsingFullText.add(timeConsumed);
break;
case DiscoveryREST_searchUsingAttribute:
discoveryREST_searchUsingAttribute.add(timeConsumed);
break;
case DiscoveryREST_searchWithParameters:
discoveryREST_searchWithParameters.add(timeConsumed);
break;
case DiscoveryREST_searchRelatedEntities:
discoveryREST_searchRelatedEntities.add(timeConsumed);
break;
case DiscoveryREST_updateSavedSearch:
discoveryREST_updateSavedSearch.add(timeConsumed);
break;
case DiscoveryREST_getSavedSearch:
discoveryREST_getSavedSearch.add(timeConsumed);
break;
case DiscoveryREST_getSavedSearches:
discoveryREST_getSavedSearches.add(timeConsumed);
break;
case DiscoveryREST_deleteSavedSearch:
discoveryREST_deleteSavedSearch.add(timeConsumed);
break;
case DiscoveryREST_executeSavedSearchByName:
discoveryREST_executeSavedSearchByName.add(timeConsumed);
break;
case DiscoveryREST_executeSavedSearchByGuid:
discoveryREST_executeSavedSearchByGuid.add(timeConsumed);
break;
case DiscoveryREST_getSuggestions:
discoveryREST_getSuggestions.add(timeConsumed);
break;
//GlossaryRest apis
case GlossaryREST_getGlossaries:
glossaryREST_getGlossaries.add(timeConsumed);
break;
case GlossaryREST_getGlossary:
glossaryREST_getGlossary.add(timeConsumed);
break;
case GlossaryREST_getDetailedGlossary:
glossaryREST_getDetailedGlossary.add(timeConsumed);
break;
case GlossaryREST_getGlossaryTerm:
glossaryREST_getGlossaryTerm.add(timeConsumed);
break;
case GlossaryREST_getGlossaryCategory:
glossaryREST_getGlossaryCategory.add(timeConsumed);
break;
case GlossaryREST_createGlossary:
glossaryREST_createGlossary.add(timeConsumed);
break;
case GlossaryREST_createGlossaryTerm:
glossaryREST_createGlossaryTerm.add(timeConsumed);
break;
case GlossaryREST_createGlossaryTerms:
glossaryREST_createGlossaryTerms.add(timeConsumed);
break;
case GlossaryREST_createGlossaryCategory:
glossaryREST_createGlossaryCategory.add(timeConsumed);
break;
case GlossaryREST_createGlossaryCategories:
glossaryREST_createGlossaryCategories.add(timeConsumed);
break;
case GlossaryREST_updateGlossary:
glossaryREST_updateGlossary.add(timeConsumed);
break;
case GlossaryREST_partialUpdateGlossary:
glossaryREST_partialUpdateGlossary.add(timeConsumed);
break;
case GlossaryREST_updateGlossaryTerm:
glossaryREST_updateGlossaryTerm.add(timeConsumed);
break;
case GlossaryREST_partialUpdateGlossaryTerm:
glossaryREST_partialUpdateGlossaryTerm.add(timeConsumed);
break;
case GlossaryREST_updateGlossaryCategory:
glossaryREST_updateGlossaryCategory.add(timeConsumed);
break;
case GlossaryREST_partialUpdateGlossaryCategory:
glossaryREST_partialUpdateGlossaryCategory.add(timeConsumed);
break;
case GlossaryREST_deleteGlossary:
glossaryREST_deleteGlossary.add(timeConsumed);
break;
case GlossaryREST_deleteGlossaryTerm:
glossaryREST_deleteGlossaryTerm.add(timeConsumed);
break;
case GlossaryREST_deleteGlossaryCategory:
glossaryREST_deleteGlossaryCategory.add(timeConsumed);
break;
case GlossaryREST_getGlossaryTerms:
glossaryREST_getGlossaryTerms.add(timeConsumed);
break;
case GlossaryREST_getGlossaryTermHeaders:
glossaryREST_getGlossaryTermHeaders.add(timeConsumed);
break;
case GlossaryREST_getGlossaryCategories:
glossaryREST_getGlossaryCategories.add(timeConsumed);
break;
case GlossaryREST_getGlossaryCategoriesHeaders:
glossaryREST_getGlossaryCategoriesHeaders.add(timeConsumed);
break;
case GlossaryREST_getCategoryTerms:
glossaryREST_getCategoryTerms.add(timeConsumed);
break;
case GlossaryREST_getRelatedTerms:
glossaryREST_getRelatedTerms.add(timeConsumed);
break;
case GlossaryREST_getEntitiesAssignedWithTerm:
glossaryREST_getEntitiesAssignedWithTerm.add(timeConsumed);
break;
case GlossaryREST_assignTermToEntities:
glossaryREST_assignTermToEntities.add(timeConsumed);
break;
case GlossaryREST_removeTermAssignmentFromEntities:
glossaryREST_removeTermAssignmentFromEntities.add(timeConsumed);
break;
case GlossaryREST_disassociateTermAssignmentFromEntities:
glossaryREST_disassociateTermAssignmentFromEntities.add(timeConsumed);
break;
case GlossaryREST_getRelatedCategories:
glossaryREST_getRelatedCategories.add(timeConsumed);
break;
case GlossaryREST_importGlossaryData:
glossaryREST_importGlossaryData.add(timeConsumed);
break;
//TypesREST apis
case TypesREST_getTypeDefByName:
typesREST_getTypeDefByName.add(timeConsumed);
break;
case TypesREST_getTypeDefByGuid:
typesREST_getTypeDefByGuid.add(timeConsumed);
break;
case TypesREST_getTypeDefHeaders:
typesREST_getTypeDefHeaders.add(timeConsumed);
break;
case TypesREST_getAllTypeDefs:
typesREST_getAllTypeDefs.add(timeConsumed);
break;
case TypesREST_getEnumDefByName:
typesREST_getEnumDefByName.add(timeConsumed);
break;
case TypesREST_getEnumDefByGuid:
typesREST_getEnumDefByGuid.add(timeConsumed);
break;
case TypesREST_getStructDefByName:
typesREST_getStructDefByName.add(timeConsumed);
break;
case TypesREST_getStructDefByGuid:
typesREST_getStructDefByGuid.add(timeConsumed);
break;
case TypesREST_getClassificationDefByName:
typesREST_getClassificationDefByName.add(timeConsumed);
break;
case TypesREST_getClassificationDefByGuid:
typesREST_getClassificationDefByGuid.add(timeConsumed);
break;
case TypesREST_getEntityDefByName:
typesREST_getEntityDefByName.add(timeConsumed);
break;
case TypesREST_getEntityDefByGuid:
typesREST_getEntityDefByGuid.add(timeConsumed);
break;
case TypesREST_getRelationshipDefByName:
typesREST_getRelationshipDefByName.add(timeConsumed);
break;
case TypesREST_getRelationshipDefByGuid:
typesREST_getRelationshipDefByGuid.add(timeConsumed);
break;
case TypesREST_getBusinessMetadataDefByGuid:
typesREST_getBusinessMetadataDefByGuid.add(timeConsumed);
break;
case TypesREST_getBusinessMetadataDefByName:
typesREST_getBusinessMetadataDefByName.add(timeConsumed);
break;
case TypesREST_createAtlasTypeDefs:
typesREST_createAtlasTypeDefs.add(timeConsumed);
break;
case TypesREST_updateAtlasTypeDefs:
typesREST_updateAtlasTypeDefs.add(timeConsumed);
break;
case TypesREST_deleteAtlasTypeDefs:
typesREST_deleteAtlasTypeDefs.add(timeConsumed);
break;
case TypesREST_deleteAtlasTypeByName:
typesREST_deleteAtlasTypeByName.add(timeConsumed);
break;
case EntityREST_getHeaderById:
entityREST_getHeaderById.add(timeConsumed);
break;
case EntityREST_getEntityHeaderByUA:
entityREST_getEntityHeaderByUniqAttr.add(timeConsumed);
break;
case EntityREST_getByUniqueAttributes:
entityREST_getByUniqueAttributes.add(timeConsumed);
break;
case EntityREST_partialUpdateEntityByUA:
entityREST_partialUpdateEntityByUniqAttr.add(timeConsumed);
break;
case EntityREST_deleteByUA:
entityREST_deleteByUniqAttr.add(timeConsumed);
break;
case EntityREST_updateClassificationsByUA:
entityREST_updateClassificationsByUniqAttr.add(timeConsumed);
break;
case EntityREST_updateClassifications:
entityREST_updateClassifications.add(timeConsumed);
break;
case EntityREST_getEntitiesByUA:
entityREST_getEntitiesByUniqAttr.add(timeConsumed);
break;
case EntityREST_getByGuids:
entityREST_getByGuids.add(timeConsumed);
break;
case EntityREST_deleteByGuids:
entityREST_deleteByGuids.add(timeConsumed);
break;
case EntityREST_addClassification:
entityREST_addClassification.add(timeConsumed);
break;
case EntityREST_getAuditEvents:
entityREST_getAuditEvents.add(timeConsumed);
break;
case EntityREST_getEntityHeaders:
entityREST_getEntityHeaders.add(timeConsumed);
break;
case EntityREST_setClassifications:
entityREST_setClassifications.add(timeConsumed);
break;
case EntityREST_addOrUpdateBusinessAttributes:
entityREST_addOrUpdateBusinessAttributes.add(timeConsumed);
break;
case EntityREST_removeBusinessAttributes:
entityREST_removeBusinessAttributes.add(timeConsumed);
break;
case EntityREST_setLabels:
entityREST_setLabels.add(timeConsumed);
break;
case EntityREST_addLabels:
entityREST_addLabels.add(timeConsumed);
break;
case EntityREST_removeLabels:
entityREST_removeLabels.add(timeConsumed);
break;
case EntityREST_getById:
entityREST_getById.add(timeConsumed);
break;
case EntityREST_createOrUpdate:
entityREST_createOrUpdate.add(timeConsumed);
break;
case EntityREST_deleteByGuid:
entityREST_deleteByGuid.add(timeConsumed);
break;
case EntityREST_getClassifications:
entityREST_getClassifications.add(timeConsumed);
break;
case EntityREST_addClassificationsByUA:
entityREST_addClassificationsByUniqAttr.add(timeConsumed);
break;
case EntityREST_addClassifications:
entityREST_addClassifications.add(timeConsumed);
break;
case EntityREST_deleteClassificationByUA:
entityREST_deleteClassificationByUniqAttr.add(timeConsumed);
break;
case EntityREST_deleteClassification:
entityREST_deleteClassification.add(timeConsumed);
break;
case EntityREST_importBMAttributes:
entityREST_importBMAttributes.add(timeConsumed);
break;
case NotificationHookConsumer_doWork:
notificationHookConsumer_doWork.add(timeConsumed);
break;
case DiscoveryREST_searchUsingDSL:
discoveryREST_searchUsingDSL.add(timeConsumed);
break;
case DiscoveryREST_searchUsingBasic:
discoveryREST_searchUsingBasic.add(timeConsumed);
break;
case DiscoveryREST_quickSearch:
discoveryREST_quickSearch.add(timeConsumed);
break;
case DiscoveryREST_addSavedSearch:
discoveryREST_addSavedSearch.add(timeConsumed);
break;
case LineageREST_getLineageByUA:
lineageREST_getLineageByUniqAttr.add(timeConsumed);
break;
case LineageREST_getLineageGraph:
lineageREST_getLineageGraph.add(timeConsumed);
break;
default:
LOG.error("The signature '{}' is not handled!", name);
break;
}
}
}

View File

@ -0,0 +1,190 @@
/*
* 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.
*/
package org.apache.atlas.web.service;
import org.apache.hadoop.metrics2.MetricsSystem;
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
import org.aspectj.lang.Signature;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import static org.apache.atlas.web.service.DebugMetricsWrapper.Constants.*;
@Lazy()
@Service
public class DebugMetricsWrapper {
private AtlasDebugMetricsSource debugMetricsSource = new AtlasDebugMetricsSource();
@Inject
AtlasDebugMetricsSink debugMetricsRESTSink;
@PostConstruct
public void init() {
MetricsSystem metricsSystem = DefaultMetricsSystem.initialize(DEBUG_METRICS_CONTEXT);
metricsSystem.register(debugMetricsSource);
metricsSystem.register(DEBUG_METRICS_REST_SINK, "", debugMetricsRESTSink);
}
public void update(Signature name, long timeConsumed) {
debugMetricsSource.update(name, timeConsumed);
}
class Constants {
public static final String NUM_OPS = "numops";
public static final String MIN_TIME = "mintime";
public static final String MAX_TIME = "maxtime";
public static final String STD_DEV_TIME = "stdevtime";
public static final String AVG_TIME = "avgtime";
public static final String DEBUG_METRICS_SOURCE = "AtlasDebugMetricsSource";
public static final String DEBUG_METRICS_CONTEXT = "atlas-debug-metrics-context";
public static final String DEBUG_METRICS_REST_SINK = "AtlasDebugMetricsRESTSink";
public static final String EntityRESTPrefix = "EntityREST.";
public static final String TypesRESTPrefix = "TypesREST.";
public static final String GlossaryRESTPrefix = "GlossaryREST.";
public static final String DiscoveryRESTPrefix = "DiscoveryREST.";
public static final String LineageRESTPrefix = "LineageREST.";
public static final String RelationshipRESTPrefix = "RelationshipREST.";
public static final String EntityREST_getById = EntityRESTPrefix + "getById(..)";
public static final String EntityREST_createOrUpdate = EntityRESTPrefix + "createOrUpdate(..)";
public static final String EntityREST_deleteByGuid = EntityRESTPrefix + "deleteByGuid(..)";
public static final String EntityREST_getClassifications = EntityRESTPrefix + "getClassifications(..)";
public static final String EntityREST_addClassificationsByUA = EntityRESTPrefix + "addClassificationsByUniqueAttribute(..)";
public static final String EntityREST_addClassifications = EntityRESTPrefix + "addClassifications(..)";
public static final String EntityREST_deleteClassificationByUA = EntityRESTPrefix + "deleteClassificationByUniqueAttribute(..)";
public static final String EntityREST_deleteClassification = EntityRESTPrefix + "deleteClassification(..)";
public static final String EntityREST_getHeaderById = EntityRESTPrefix + "getHeaderById(..)";
public static final String EntityREST_getEntityHeaderByUA = EntityRESTPrefix + "getEntityHeaderByUniqueAttributes(..)";
public static final String EntityREST_getByUniqueAttributes = EntityRESTPrefix + "getByUniqueAttributes(..)";
public static final String EntityREST_partialUpdateEntityByUA = EntityRESTPrefix + "partialUpdateEntityByUniqueAttrs(..)";
public static final String EntityREST_deleteByUA = EntityRESTPrefix + "deleteByUniqueAttribute(..)";
public static final String EntityREST_updateClassificationsByUA = EntityRESTPrefix + "updateClassificationsByUniqueAttribute(..)";
public static final String EntityREST_updateClassifications = EntityRESTPrefix + "updateClassifications(..)";
public static final String EntityREST_getEntitiesByUA = EntityRESTPrefix + "getEntitiesByUniqueAttributes(..)";
public static final String EntityREST_getByGuids = EntityRESTPrefix + "getByGuids(..)";
public static final String EntityREST_deleteByGuids = EntityRESTPrefix + "deleteByGuids(..)";
public static final String EntityREST_addClassification = EntityRESTPrefix + "addClassification(..)";
public static final String EntityREST_getAuditEvents = EntityRESTPrefix + "getAuditEvents(..)";
public static final String EntityREST_getEntityHeaders = EntityRESTPrefix + "getEntityHeaders(..)";
public static final String EntityREST_setClassifications = EntityRESTPrefix + "setClassifications(..)";
public static final String EntityREST_addOrUpdateBusinessAttributes = EntityRESTPrefix + "addOrUpdateBusinessAttributes(..)";
public static final String EntityREST_removeBusinessAttributes = EntityRESTPrefix + "removeBusinessAttributes(..)";
public static final String EntityREST_setLabels = EntityRESTPrefix + "setLabels(..)";
public static final String EntityREST_addLabels = EntityRESTPrefix + "addLabels(..)";
public static final String EntityREST_removeLabels = EntityRESTPrefix + "removeLabels(..)";
public static final String EntityREST_importBMAttributes = EntityRESTPrefix + "importBMAttributes(..)";
//TypesREST
public static final String TypesREST_getTypeDefByName = TypesRESTPrefix + "getTypeDefByName(..)";
public static final String TypesREST_getTypeDefByGuid = TypesRESTPrefix + "getTypeDefByGuid(..)";
public static final String TypesREST_getTypeDefHeaders = TypesRESTPrefix + "getTypeDefHeaders(..)";
public static final String TypesREST_getAllTypeDefs = TypesRESTPrefix + "getAllTypeDefs(..)";
public static final String TypesREST_getEnumDefByName = TypesRESTPrefix + "getEnumDefByName(..)";
public static final String TypesREST_getEnumDefByGuid = TypesRESTPrefix + "getEnumDefByGuid(..)";
public static final String TypesREST_getStructDefByName = TypesRESTPrefix + "getStructDefByName(..)";
public static final String TypesREST_getStructDefByGuid = TypesRESTPrefix + "getStructDefByGuid(..)";
public static final String TypesREST_getClassificationDefByName = TypesRESTPrefix + "getClassificationDefByName(..)";
public static final String TypesREST_getClassificationDefByGuid = TypesRESTPrefix + "getClassificationDefByGuid(..)";
public static final String TypesREST_getEntityDefByName = TypesRESTPrefix + "getEntityDefByName(..)";
public static final String TypesREST_getEntityDefByGuid = TypesRESTPrefix + "getEntityDefByGuid(..)";
public static final String TypesREST_getRelationshipDefByName = TypesRESTPrefix + "getRelationshipDefByName(..)";
public static final String TypesREST_getRelationshipDefByGuid = TypesRESTPrefix + "getRelationshipDefByGuid(..)";
public static final String TypesREST_getBusinessMetadataDefByGuid = TypesRESTPrefix + "getBusinessMetadataDefByGuid(..)";
public static final String TypesREST_getBusinessMetadataDefByName = TypesRESTPrefix + "getBusinessMetadataDefByName(..)";
public static final String TypesREST_createAtlasTypeDefs = TypesRESTPrefix + "createAtlasTypeDefs(..)";
public static final String TypesREST_updateAtlasTypeDefs = TypesRESTPrefix + "updateAtlasTypeDefs(..)";
public static final String TypesREST_deleteAtlasTypeDefs = TypesRESTPrefix + "deleteAtlasTypeDefs(..)";
public static final String TypesREST_deleteAtlasTypeByName = TypesRESTPrefix + "deleteAtlasTypeByName(..)";
//GlossaryREST
public static final String GlossaryREST_getGlossaries = GlossaryRESTPrefix + "getGlossaries(..)";
public static final String GlossaryREST_getGlossary = GlossaryRESTPrefix + "getGlossary(..)";
public static final String GlossaryREST_getDetailedGlossary = GlossaryRESTPrefix + "getDetailedGlossary(..)";
public static final String GlossaryREST_getGlossaryTerm = GlossaryRESTPrefix + "getGlossaryTerm(..)";
public static final String GlossaryREST_getGlossaryCategory = GlossaryRESTPrefix + "getGlossaryCategory(..)";
public static final String GlossaryREST_createGlossary = GlossaryRESTPrefix + "createGlossary(..)";
public static final String GlossaryREST_createGlossaryTerm = GlossaryRESTPrefix + "createGlossaryTerm(..)";
public static final String GlossaryREST_createGlossaryTerms = GlossaryRESTPrefix + "createGlossaryTerms(..)";
public static final String GlossaryREST_createGlossaryCategory = GlossaryRESTPrefix + "createGlossaryCategory(..)";
public static final String GlossaryREST_createGlossaryCategories = GlossaryRESTPrefix + "createGlossaryCategories(..)";
public static final String GlossaryREST_updateGlossary = GlossaryRESTPrefix + "updateGlossary(..)";
public static final String GlossaryREST_partialUpdateGlossary = GlossaryRESTPrefix + "partialUpdateGlossary(..)";
public static final String GlossaryREST_updateGlossaryTerm = GlossaryRESTPrefix + "updateGlossaryTerm(..)";
public static final String GlossaryREST_partialUpdateGlossaryTerm = GlossaryRESTPrefix + "partialUpdateGlossaryTerm(..)";
public static final String GlossaryREST_updateGlossaryCategory = GlossaryRESTPrefix + "updateGlossaryCategory(..)";
public static final String GlossaryREST_partialUpdateGlossaryCategory = GlossaryRESTPrefix + "partialUpdateGlossaryCategory(..)";
public static final String GlossaryREST_deleteGlossary = GlossaryRESTPrefix + "deleteGlossary(..)";
public static final String GlossaryREST_deleteGlossaryTerm = GlossaryRESTPrefix + "deleteGlossaryTerm(..)";
public static final String GlossaryREST_deleteGlossaryCategory = GlossaryRESTPrefix + "deleteGlossaryCategory(..)";
public static final String GlossaryREST_getGlossaryTerms = GlossaryRESTPrefix + "getGlossaryTerms(..)";
public static final String GlossaryREST_getGlossaryTermHeaders = GlossaryRESTPrefix + "getGlossaryTermHeaders(..)";
public static final String GlossaryREST_getGlossaryCategories = GlossaryRESTPrefix + "getGlossaryCategories(..)";
public static final String GlossaryREST_getGlossaryCategoriesHeaders = GlossaryRESTPrefix + "getGlossaryCategoriesHeaders(..)";
public static final String GlossaryREST_getCategoryTerms = GlossaryRESTPrefix + "getCategoryTerms(..)";
public static final String GlossaryREST_getRelatedTerms = GlossaryRESTPrefix + "getRelatedTerms(..)";
public static final String GlossaryREST_getEntitiesAssignedWithTerm = GlossaryRESTPrefix + "getEntitiesAssignedWithTerm(..)";
public static final String GlossaryREST_assignTermToEntities = GlossaryRESTPrefix + "assignTermToEntities(..)";
public static final String GlossaryREST_removeTermAssignmentFromEntities = GlossaryRESTPrefix + "removeTermAssignmentFromEntities(..)";
public static final String GlossaryREST_disassociateTermAssignmentFromEntities = GlossaryRESTPrefix + "disassociateTermAssignmentFromEntities(..)";
public static final String GlossaryREST_getRelatedCategories = GlossaryRESTPrefix + "getRelatedCategories(..)";
public static final String GlossaryREST_importGlossaryData = GlossaryRESTPrefix + "importGlossaryData(..)";
//DiscoveryREST
public static final String DiscoveryREST_searchUsingDSL = DiscoveryRESTPrefix + "searchUsingDSL(..)";
public static final String DiscoveryREST_searchUsingBasic = DiscoveryRESTPrefix + "searchUsingBasic(..)";
public static final String DiscoveryREST_quickSearch = DiscoveryRESTPrefix + "quickSearch(..)";
public static final String DiscoveryREST_addSavedSearch = DiscoveryRESTPrefix + "addSavedSearch(..)";
public static final String DiscoveryREST_searchUsingFullText = DiscoveryRESTPrefix + "searchUsingFullText(..)";
public static final String DiscoveryREST_searchUsingAttribute = DiscoveryRESTPrefix + "searchUsingAttribute(..)";
public static final String DiscoveryREST_searchWithParameters = DiscoveryRESTPrefix + "searchWithParameters(..)";
public static final String DiscoveryREST_searchRelatedEntities = DiscoveryRESTPrefix + "searchRelatedEntities(..)";
public static final String DiscoveryREST_updateSavedSearch = DiscoveryRESTPrefix + "updateSavedSearch(..)";
public static final String DiscoveryREST_getSavedSearch = DiscoveryRESTPrefix + "getSavedSearch(..)";
public static final String DiscoveryREST_getSavedSearches = DiscoveryRESTPrefix + "getSavedSearches(..)";
public static final String DiscoveryREST_deleteSavedSearch = DiscoveryRESTPrefix + "deleteSavedSearch(..)";
public static final String DiscoveryREST_executeSavedSearchByName = DiscoveryRESTPrefix + "executeSavedSearchByName(..)";
public static final String DiscoveryREST_executeSavedSearchByGuid = DiscoveryRESTPrefix + "executeSavedSearchByGuid(..)";
public static final String DiscoveryREST_getSuggestions = DiscoveryRESTPrefix + "getSuggestions(..)";
//RelationshipREST
public static final String RelationshipREST_create = RelationshipRESTPrefix + "create(..)";
public static final String RelationshipREST_update = RelationshipRESTPrefix + "update(..)";
public static final String RelationshipREST_getById = RelationshipRESTPrefix + "getById(..)";
public static final String RelationshipREST_deleteById = RelationshipRESTPrefix + "deleteById(..)";
public static final String LineageREST_getLineageByUA = LineageRESTPrefix + "getLineageByUniqueAttribute(..)";
public static final String LineageREST_getLineageGraph = LineageRESTPrefix + "getLineageGraph(..)";
public static final String NotificationHookConsumer_doWork = "NotificationHookConsumer.doWork(..)";
//duplicate short signature apis
public static final String EntityREST_createOrUpdateBulk = "EntityMutationResponse org.apache.atlas.web.rest.EntityREST.createOrUpdate(AtlasEntitiesWithExtInfo)";
public static final String EntityREST_removeLabelsByTypeName = "void org.apache.atlas.web.rest.EntityREST.removeLabels(String,Set,HttpServletRequest)";
public static final String EntityREST_setLabelsByTypeName = "void org.apache.atlas.web.rest.EntityREST.setLabels(String,Set,HttpServletRequest)";
public static final String EntityREST_addLabelsByTypeName = "void org.apache.atlas.web.rest.EntityREST.addLabels(String,Set,HttpServletRequest)";
public static final String EntityREST_addOrUpdateBMByName = "void org.apache.atlas.web.rest.EntityREST.addOrUpdateBusinessAttributes(String,String,Map)";
public static final String EntityREST_removeBMByName = "void org.apache.atlas.web.rest.EntityREST.removeBusinessAttributes(String,String,Map)";
public static final String DiscoveryREST_quickSearchQuickSearchParams = "AtlasQuickSearchResult org.apache.atlas.web.rest.DiscoveryREST.quickSearch(QuickSearchParameters)";
}
}

View File

@ -0,0 +1,61 @@
/**
* 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.
*/
package org.apache.atlas.web.service;
import org.apache.atlas.AtlasConfiguration;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
@Aspect
@Component
public class TimedAspectInterceptor {
private static final boolean debugMetricsEnabled = AtlasConfiguration.DEBUG_METRICS_ENABLED.getBoolean();
private final DebugMetricsWrapper wrapper;
@Inject
public TimedAspectInterceptor(DebugMetricsWrapper wrapper) {
this.wrapper = wrapper;
}
@Around("@annotation(org.apache.atlas.annotation.Timed) && execution(public * *(..))")
public Object timerAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long start = System.currentTimeMillis();
try {
return proceedingJoinPoint.proceed();
} catch (Throwable throwable){
throw throwable;
} finally {
if (debugMetricsEnabled) {
reportMetrics(start, proceedingJoinPoint.getSignature());
}
}
}
private void reportMetrics(long start, Signature signature) {
long executionTime = System.currentTimeMillis() - start;
wrapper.update(signature, executionTime);
}
}

View File

@ -637,6 +637,16 @@ public abstract class BaseResourceIT {
return atlasEntity;
}
protected AtlasEntity createEntity(String typeName, String name) {
AtlasEntity atlasEntity = new AtlasEntity(typeName);
atlasEntity.setAttribute("name", name);
atlasEntity.setAttribute("qualifiedName", name);
atlasEntity.setAttribute("clusterName", randomString());
return atlasEntity;
}
public interface Predicate {
/**

View File

@ -0,0 +1,79 @@
/**
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.
*/
package org.apache.atlas.web.integration;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.atlas.AtlasBaseClient;
import org.apache.atlas.model.instance.AtlasEntity;
import org.apache.atlas.utils.AtlasJson;
import org.apache.atlas.web.model.DebugMetrics;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
public class DebugMetricsIT extends BaseResourceIT {
@BeforeClass
public void setUp() throws Exception {
super.setUp();
}
@Test
public void checkMetricCountIncrement() {
// Get the metrics
AtlasBaseClient.API metricsAPI = new AtlasBaseClient.API(AtlasBaseClient.BASE_URI + "admin/debug/metrics", HttpMethod.GET, Response.Status.OK);
try {
String metricsJson = atlasClientV1.callAPI(metricsAPI, String.class, null);
HashMap<String, DebugMetrics> currentMetrics = AtlasJson.fromJson(metricsJson, new TypeReference<HashMap<String, DebugMetrics>>() {});
DebugMetrics currentCreateOrUpdateDTO = currentMetrics.get("EntityREST_createOrUpdate");
long currentCreateOrUpdateCount = 0;
if(currentCreateOrUpdateDTO != null) {
currentCreateOrUpdateCount = currentCreateOrUpdateDTO.getNumops();
}
// hit the api
AtlasEntity atlasEntity = createEntity(DATABASE_TYPE_BUILTIN, randomString());
atlasClientV2.createEntity(new AtlasEntity.AtlasEntityWithExtInfo(atlasEntity));
atlasEntity = createEntity(DATABASE_TYPE_BUILTIN, randomString());
atlasClientV2.createEntity(new AtlasEntity.AtlasEntityWithExtInfo(atlasEntity));
// get the metrics again
Thread.sleep(30000); // The metrics take some time to update
metricsJson = atlasClientV1.callAPI(metricsAPI, String.class, null);
HashMap<String, DebugMetrics> newMetrics = AtlasJson.fromJson(metricsJson, new TypeReference<HashMap<String, DebugMetrics>>() {});
DebugMetrics newCreateOrUpdateDTO = newMetrics.get("EntityREST_createOrUpdate");
// check if the metric count has increased
long newCreateOrUpdateCount = 0;
if(newCreateOrUpdateDTO != null) {
newCreateOrUpdateCount = newCreateOrUpdateDTO.getNumops();
}
assertEquals(newCreateOrUpdateCount, (currentCreateOrUpdateCount + 2), "Count didn't increase after making API call");
} catch (Exception e) {
fail("Caught exception while running the test: " + e.getMessage(), e);
}
}
}

View File

@ -51,7 +51,7 @@ public class AdminResourceTest {
when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.ACTIVE);
AdminResource adminResource = new AdminResource(serviceState, null, null, null, null, null, null, null, null, null, null, null, null, null);
AdminResource adminResource = new AdminResource(serviceState, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
Response response = adminResource.getStatus();
assertEquals(response.getStatus(), HttpServletResponse.SC_OK);
JsonNode entity = AtlasJson.parseToV1JsonNode((String) response.getEntity());
@ -62,7 +62,7 @@ public class AdminResourceTest {
public void testResourceGetsValueFromServiceState() throws IOException {
when(serviceState.getState()).thenReturn(ServiceState.ServiceStateValue.PASSIVE);
AdminResource adminResource = new AdminResource(serviceState, null, null, null, null, null, null, null, null, null, null, null, null, null);
AdminResource adminResource = new AdminResource(serviceState, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
Response response = adminResource.getStatus();
verify(serviceState).getState();