mirror of https://github.com/apache/nifi.git
NIFI-2182:
- Ensuring the active thread count is shown. NIFI-2019: - Ensuring correct color of the run status in the From connection label. NIFI-2183: - Removing the DownloadSvg servlet and hidding the download icon until we're able to support save the svg entirely from the client side. This closes #634.
This commit is contained in:
parent
8ab9fca7f8
commit
1e1630cc69
|
@ -1,88 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.nifi.web.servlet;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DownloadSvg extends HttpServlet {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DownloadSvg.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param request servlet request
|
|
||||||
* @param response servlet response
|
|
||||||
* @throws ServletException if a servlet-specific error occurs
|
|
||||||
* @throws IOException if an I/O error occurs
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
|
||||||
final String svg = request.getParameter("svg");
|
|
||||||
|
|
||||||
// ensure the image markup has been included
|
|
||||||
if (svg == null) {
|
|
||||||
// set the response status
|
|
||||||
response.setContentType("text/plain");
|
|
||||||
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
|
||||||
|
|
||||||
// write the response message
|
|
||||||
PrintWriter out = response.getWriter();
|
|
||||||
out.println("SVG must be specified.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug(svg);
|
|
||||||
}
|
|
||||||
|
|
||||||
String filename = request.getParameter("filename");
|
|
||||||
if (filename == null) {
|
|
||||||
filename = "image.svg";
|
|
||||||
} else if (!filename.endsWith(".svg")) {
|
|
||||||
filename += ".svg";
|
|
||||||
}
|
|
||||||
|
|
||||||
response.setContentType("image/svg+xml");
|
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
|
|
||||||
response.setStatus(HttpServletResponse.SC_OK);
|
|
||||||
|
|
||||||
response.getWriter().print(svg);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
|
|
||||||
// set the response status
|
|
||||||
response.setContentType("text/plain");
|
|
||||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
|
||||||
|
|
||||||
// write the response message
|
|
||||||
PrintWriter out = response.getWriter();
|
|
||||||
out.println("Unable to export image as a SVG.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -56,7 +56,7 @@
|
||||||
<div id="provenance-lineage-loading" class="loading-container"></div>
|
<div id="provenance-lineage-loading" class="loading-container"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="provenance-lineage-close-container">
|
<div id="provenance-lineage-close-container">
|
||||||
<div id="provenance-lineage-downloader" title="Download"></div>
|
<div id="provenance-lineage-downloader" class="hidden" title="Download"></div>
|
||||||
<div id="provenance-lineage-closer" title="Close"></div>
|
<div id="provenance-lineage-closer" title="Close"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="provenance-lineage-context-menu"></div>
|
<div id="provenance-lineage-context-menu"></div>
|
||||||
|
|
|
@ -116,16 +116,6 @@
|
||||||
<url-pattern>/message</url-pattern>
|
<url-pattern>/message</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
<!-- servlet to support image downloading -->
|
|
||||||
<servlet>
|
|
||||||
<servlet-name>DownloadSvg</servlet-name>
|
|
||||||
<servlet-class>org.apache.nifi.web.servlet.DownloadSvg</servlet-class>
|
|
||||||
</servlet>
|
|
||||||
<servlet-mapping>
|
|
||||||
<servlet-name>DownloadSvg</servlet-name>
|
|
||||||
<url-pattern>/download-svg</url-pattern>
|
|
||||||
</servlet-mapping>
|
|
||||||
|
|
||||||
<!-- servlet to login page -->
|
<!-- servlet to login page -->
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>Login</servlet-name>
|
<servlet-name>Login</servlet-name>
|
||||||
|
|
|
@ -427,11 +427,11 @@ nf.CanvasUtils = (function () {
|
||||||
*/
|
*/
|
||||||
activeThreadCount: function (selection, d, setOffset) {
|
activeThreadCount: function (selection, d, setOffset) {
|
||||||
// if there is active threads show the count, otherwise hide
|
// if there is active threads show the count, otherwise hide
|
||||||
if (nf.Common.isDefinedAndNotNull(d.status) && d.status.activeThreadCount > 0) {
|
if (nf.Common.isDefinedAndNotNull(d.status) && d.status.aggregateSnapshot.activeThreadCount > 0) {
|
||||||
// update the active thread count
|
// update the active thread count
|
||||||
var activeThreadCount = selection.select('text.active-thread-count')
|
var activeThreadCount = selection.select('text.active-thread-count')
|
||||||
.text(function () {
|
.text(function () {
|
||||||
return d.status.activeThreadCount;
|
return d.status.aggregateSnapshot.activeThreadCount;
|
||||||
})
|
})
|
||||||
.style('display', 'block')
|
.style('display', 'block')
|
||||||
.each(function () {
|
.each(function () {
|
||||||
|
|
|
@ -787,7 +787,7 @@ nf.Connection = (function () {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.classed('is-missing-port', function () {
|
.classed('is-missing-port', function () {
|
||||||
return d.component.source.exists === true;
|
return d.component.source.exists === false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// there is no connection from, but check if the name was previous
|
// there is no connection from, but check if the name was previous
|
||||||
|
|
|
@ -250,7 +250,7 @@ nf.Port = (function () {
|
||||||
details.append('text')
|
details.append('text')
|
||||||
.attr({
|
.attr({
|
||||||
'class': 'active-thread-count-icon',
|
'class': 'active-thread-count-icon',
|
||||||
'y': 68
|
'y': 43 + offset
|
||||||
})
|
})
|
||||||
.text('\ue83f');
|
.text('\ue83f');
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ nf.Port = (function () {
|
||||||
details.append('text')
|
details.append('text')
|
||||||
.attr({
|
.attr({
|
||||||
'class': 'active-thread-count',
|
'class': 'active-thread-count',
|
||||||
'y': 68
|
'y': 43 + offset
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -724,41 +724,6 @@ nf.Common = (function () {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a form inline in order to submit the specified params to the specified URL
|
|
||||||
* using the specified method.
|
|
||||||
*
|
|
||||||
* @param {string} url The URL
|
|
||||||
* @param {object} params An object with the params to include in the submission
|
|
||||||
*/
|
|
||||||
post: function (url, params) {
|
|
||||||
// temporarily override beforeunload
|
|
||||||
var previousBeforeUnload = window.onbeforeunload;
|
|
||||||
window.onbeforeunload = null;
|
|
||||||
|
|
||||||
// create a form for submission
|
|
||||||
var form = $('<form></form>').attr({
|
|
||||||
'method': 'POST',
|
|
||||||
'action': url,
|
|
||||||
'style': 'display: none;'
|
|
||||||
});
|
|
||||||
|
|
||||||
// add each parameter when specified
|
|
||||||
if (nf.Common.isDefinedAndNotNull(params)) {
|
|
||||||
$.each(params, function (name, value) {
|
|
||||||
$('<textarea></textarea>').attr('name', name).val(value).appendTo(form);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// submit the form and clean up
|
|
||||||
form.appendTo('body').submit().remove();
|
|
||||||
|
|
||||||
// restore previous beforeunload if necessary
|
|
||||||
if (previousBeforeUnload !== null) {
|
|
||||||
window.onbeforeunload = previousBeforeUnload;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats the specified array as an unordered list. If the array is not an
|
* Formats the specified array as an unordered list. If the array is not an
|
||||||
* array, null is returned.
|
* array, null is returned.
|
||||||
|
|
|
@ -1237,67 +1237,69 @@ nf.ProvenanceLineage = (function () {
|
||||||
$('#provenance-event-search').show();
|
$('#provenance-event-search').show();
|
||||||
$('#provenance-lineage').hide();
|
$('#provenance-lineage').hide();
|
||||||
});
|
});
|
||||||
$('#provenance-lineage-downloader').on('click', function () {
|
|
||||||
var svg = $('#provenance-lineage-container').html();
|
|
||||||
|
|
||||||
// get the lineage to determine the actual dimensions
|
// TODO - restore this as necessary when able to download lineage svg entirely client side
|
||||||
var lineage = $('g.lineage')[0];
|
// $('#provenance-lineage-downloader').on('click', function () {
|
||||||
var bbox = lineage.getBBox();
|
// var svg = $('#provenance-lineage-container').html();
|
||||||
|
//
|
||||||
// adjust to provide some padding
|
// // get the lineage to determine the actual dimensions
|
||||||
var height = bbox.height + 30;
|
// var lineage = $('g.lineage')[0];
|
||||||
var width = bbox.width + 30;
|
// var bbox = lineage.getBBox();
|
||||||
var offsetX = bbox.x - 15;
|
//
|
||||||
var offsetY = bbox.y - 15;
|
// // adjust to provide some padding
|
||||||
|
// var height = bbox.height + 30;
|
||||||
// replace the svg height, width with the actual values
|
// var width = bbox.width + 30;
|
||||||
svg = svg.replace(/height=".*?"/, 'height="' + height + '"');
|
// var offsetX = bbox.x - 15;
|
||||||
svg = svg.replace(/width=".*?"/, 'width="' + width + '"');
|
// var offsetY = bbox.y - 15;
|
||||||
|
//
|
||||||
// remove any transform applied to the lineage
|
// // replace the svg height, width with the actual values
|
||||||
svg = svg.replace(/transform=".*?"/, '');
|
// svg = svg.replace(/height=".*?"/, 'height="' + height + '"');
|
||||||
|
// svg = svg.replace(/width=".*?"/, 'width="' + width + '"');
|
||||||
// adjust link positioning based on the offset of the bounding box
|
//
|
||||||
svg = svg.replace(/<path([^>]*?)d="M[\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?L[\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?"(.*?)>/g, function (match, before, rawMoveX, rawMoveY, rawLineX, rawLineY, after) {
|
// // remove any transform applied to the lineage
|
||||||
// this regex captures the content before and after the d attribute in order to ensure that it contains the link class.
|
// svg = svg.replace(/transform=".*?"/, '');
|
||||||
// within the svg image, there are other paths that are (within markers) that we do not want to offset
|
//
|
||||||
if (before.indexOf('link') === -1 && after.indexOf('link') === -1) {
|
// // adjust link positioning based on the offset of the bounding box
|
||||||
return match;
|
// svg = svg.replace(/<path([^>]*?)d="M[\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?L[\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?"(.*?)>/g, function (match, before, rawMoveX, rawMoveY, rawLineX, rawLineY, after) {
|
||||||
}
|
// // this regex captures the content before and after the d attribute in order to ensure that it contains the link class.
|
||||||
|
// // within the svg image, there are other paths that are (within markers) that we do not want to offset
|
||||||
var moveX = parseFloat(rawMoveX) - offsetX;
|
// if (before.indexOf('link') === -1 && after.indexOf('link') === -1) {
|
||||||
var moveY = parseFloat(rawMoveY) - offsetY;
|
// return match;
|
||||||
var lineX = parseFloat(rawLineX) - offsetX;
|
// }
|
||||||
var lineY = parseFloat(rawLineY) - offsetY;
|
//
|
||||||
return '<path' + before + 'd="M' + moveX + ',' + moveY + 'L' + lineX + ',' + lineY + '"' + after + '>';
|
// var moveX = parseFloat(rawMoveX) - offsetX;
|
||||||
});
|
// var moveY = parseFloat(rawMoveY) - offsetY;
|
||||||
|
// var lineX = parseFloat(rawLineX) - offsetX;
|
||||||
// adjust node positioning based on the offset of the bounding box
|
// var lineY = parseFloat(rawLineY) - offsetY;
|
||||||
svg = svg.replace(/<g([^>]*?)transform="translate\([\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?\)"(.*?)>/g, function (match, before, rawX, rawY, after) {
|
// return '<path' + before + 'd="M' + moveX + ',' + moveY + 'L' + lineX + ',' + lineY + '"' + after + '>';
|
||||||
// this regex captures the content before and after the transform attribute in order to ensure that it contains the
|
// });
|
||||||
// node class. only node groups are translated with absolute coordinates since all other translated groups fall under
|
//
|
||||||
// a parent that is already positioned. this makes their translation relative and not appropriate for this adjustment
|
// // adjust node positioning based on the offset of the bounding box
|
||||||
if (before.indexOf('node') === -1 && after.indexOf('node') === -1) {
|
// svg = svg.replace(/<g([^>]*?)transform="translate\([\s]?([^\s]+?)[\s,]([^\s]+?)[\s]?\)"(.*?)>/g, function (match, before, rawX, rawY, after) {
|
||||||
return match;
|
// // this regex captures the content before and after the transform attribute in order to ensure that it contains the
|
||||||
}
|
// // node class. only node groups are translated with absolute coordinates since all other translated groups fall under
|
||||||
|
// // a parent that is already positioned. this makes their translation relative and not appropriate for this adjustment
|
||||||
var x = parseFloat(rawX) - offsetX;
|
// if (before.indexOf('node') === -1 && after.indexOf('node') === -1) {
|
||||||
var y = parseFloat(rawY) - offsetY;
|
// return match;
|
||||||
return '<g' + before + 'transform="translate(' + x + ',' + y + ')"' + after + '>';
|
// }
|
||||||
});
|
//
|
||||||
|
// var x = parseFloat(rawX) - offsetX;
|
||||||
// namespaces
|
// var y = parseFloat(rawY) - offsetY;
|
||||||
svg = svg.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"');
|
// return '<g' + before + 'transform="translate(' + x + ',' + y + ')"' + after + '>';
|
||||||
|
// });
|
||||||
// doctype
|
//
|
||||||
svg = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + svg;
|
// // namespaces
|
||||||
|
// svg = svg.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"');
|
||||||
// send to server to initiate download... client side only support is too browser specific at this point
|
//
|
||||||
nf.Common.post('./download-svg', {
|
// // doctype
|
||||||
'filename': 'provenance',
|
// svg = '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + svg;
|
||||||
'svg': svg
|
//
|
||||||
});
|
// // send to server to initiate download... client side only support is too browser specific at this point
|
||||||
});
|
// nf.Common.post('./download-svg', {
|
||||||
|
// 'filename': 'provenance',
|
||||||
|
// 'svg': svg
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
initLineageQueryDialog();
|
initLineageQueryDialog();
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue