Where can i find the debug information in zuul? - netflix-zuul

I want to use debugFilter in ZUUL. when i post param "debug=true" in query string, I can't find the debug info in my standard output.
Where can i find the debug information?

If you call api with param debug=true, debugging information will be accumulated into RequestContext with a key routingDebug. The value is List<String> type.
If you set the properties like below, debug info will be added into response-header - X-Zuul-Debug-Header.
zuul.include-debug-header=true
As far as I know, this information is not printed out to standard out as default.
Instead, you can easily access this info via com.netflix.zuul.context.Debug.getRoutingDebug().
You can make your own post filter to print out this info easily like below.
#Override
public boolean shouldFilter() {
return Debug.debugRouting();
}
#Override
public Object run() {
String debug = convertToPrettyPrintString(Debug.getRoutingDebug());
log.info("Filter Debug Info = \n{}", debug);
// or System.out.println(...)
return null;
}
private String convertToPrettyPrintString(List<String> filterDebugList) {
return filterDebugList.stream()
.map(s -> s.startsWith("{") ? "\t" + s : s)
.collect(Collectors.joining("\n"));
}

Related

AllureRestAssured , how to ignore logging headers

I am using rest-assured and allureRestAssured for testing api ,
given().header("Content-Type", "application/json")
.header("key", key()).filter(new AllureRestAssured())
.body(body.toString())
.post(baseURI);
Problem here is its logged headers also , which contains auth key , which I dont want to be exposed in report generated , how can I ignore that .
You can extend the AllureRestAssured filter and override it. There is the private method toMapConverter I add it to my implementation. I just remove by Key what I don't want to show in the report.
private static Map<String, String> toMapConverter(final Iterable<? extends NameAndValue> items) {
final Map<String, String> result = new HashMap<>();
items.forEach(h -> result.put(h.getName(), h.getValue()));
result.remove("key");
return result;
}

How do I use SimpleFileVisitor in Java to find a file name whose encoding may vary?

I'm using SimpleFileVisitor to search for a file. It works fine on Windows and Linux. However when I try using it on Unix like operating systems It doesn't work as expected. I would get errors like this:
java.nio.file.NoSuchFileException:
/File/Location/MyFolder/\u0082\u0096\u0096âĜu0099\u0081\u0097K
\u0097\u0099\u0096\u0097\u0085\u0099Ĝu0089\u0085
It looks like the obtained name is in different character encoding and maybe that is what causing the issue. It looks like in between the obtaining the name and trying to obtain the access to the file, the encoding is getting missed up. This result in calling preVisitDirectory once then visitFileFailed for every file it tries to visit. I'm not sure why the walkFileTree method is doing that. Any idea?
My using for SimpleFileVisitor code looks like this:
Files.walkFileTree(serverLocation, finder);
My SimpleFileVisitor class:
public class Finder extends SimpleFileVisitor<Path> {
private final PathMatcher matcher;
private final List<Path> matchedPaths = new ArrayList<Path>();
private String usedPattern = null;
Finder(String pattern) {
this.usedPattern = pattern;
matcher = FileSystems.getDefault().getPathMatcher("glob:" + pattern);
}
void match(Path file) { //Compare pattern against file or dir
Path name = file.getFileName();
if (name != null && matcher.matches(name))
matchedPaths.add(file);
}
// Check each file.
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
match(file);
return CONTINUE;
}
// Check each directory.
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
match(dir);
return CONTINUE;
}
#Override
public FileVisitResult visitFileFailed(Path file, IOException e) {
System.out.println("Issue: " + e );
return CONTINUE;
}
Try using "Charset.defaultCharset()" when you create those "file" and "dir" strings you pass around. Otherwise, you could very likely mangle the names in the process of creating those strings to pass them to your visit methods.
You might also check your default encoding on the JVM your are running, if it is out of sync with the file system you are reading, your results will be, err, unpredictable.

PrimeFaces DataTable: (Multi)selection does not work for dynamically built tables giving only nulls

I'm working with the multiple row selection to give a user ability to delete the selecting records. According to the PDF documentation, and the ShowCase Labs, I must use the code translated to the Java like that:
final DataTable = new DataTable();
...
// (1)
dataTable.setSelectionMode("multiple");
// (2)
dataTable.setValueExpression("selection", createValueExpression(DbeBean.class, "selection", Object[].class));
// (3)
dataTable.setValueExpression("rowKey", createValueExpression("#{" + VARIABLE + ".indexKey}", Object.class));
...
final ClientBehaviorHolder dataTableAsHolder = dataTable;
...
// (4)
dataTableAsHolder.addClientBehavior("rowSelect", createAjaxBehavior(createMethodExpression(metaData.controllerBeanType, "onRowSelect", void.class, new Class<?>[] {SelectEvent.class})));
multiple - This line features the multiple selection, works fine visually at the front-end.
selection - Being invoked, the #{dbeBean.selection} is really bound and the public void setSelection(T[] selection) is only invoked.
rowKey - Being invoked, works fine, the getIndexKey() is invoked and returns the necessary result.
rowSelect - This event handler is invoked too, DbeBean.onRowSelect(SelectEvent e).
I also use lazy data model (I don't really believe it may be the reason but who knows?; by the way, it returns List<T> though setSelection() requires T[] -- why it's like that?):
public abstract class AbstractLazyDataSource<T extends IIndexable<K>, K> extends LazyDataModel<T> {
...
#Override
public final List<T> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
...
final IResultContainer<T> resultContainer = getData(querySpecifier);
final List<T> data = resultContainer.getData();
setRowCount(resultContainer.getTotalEntitiesCount());
return getPage(data, first, pageSize);
}
...
#Override
public final K getRowKey(T object) {
return object.getIndexKey(); // T instanceof IIndexable<K>, have to return a unique ID
}
...
However, the handlers do not work as they are expected to work. Please help me to understand why (2) DbeBean.setSelection(T[] selection) & (4) DbeBean.onRowSelect(SelectEvent e) get only the null value: T[] selection = null, and SelectEvent: e.getObject = null, respectively. What am I doing wrong?
Thanks in advance.
PrimeFaces 3.2
Mojarra 2.1.7
I've got it to work: I simply removed the rowKey property during to the dynamic p:dataTable creation (DataTable), and simply overloaded getRowData in lazy data model. Now it works.

Memory overusage in Play! Framework method call

In one of my Controllers, I have multiple URLs that will ultimately render in the same way. For example, this method scans the network on which the server resides, caches a String representation of each connected device and each device listening on a specific port, and then sends that information to another method to render:
public static void networkScan(String networkTarget, String port)
{
//These two lists will never have more than 256 total entries
List<InetSocketAddress> listeningDevices;
Map<String, String> allDevices;
...Logic for discovering network devices...
//Store the results in a cache, for history preservation in the browser
Cache.set(session.getId() + "listeningDevices", listeningDevices);
Cache.set(session.getId() + "allDevices", allDevices);
showScan(listeningDevices, allDevices);
}
public static void showScan(List<InetSocketAddress> listeningDevices, Map<String, String> allDevices)
{
render(listeningDevices, allDevices);
}
public static void getCachedScan()
{
List<InetSocketAddress> listeningDevices = (List<InetSocketAddress>)Cache.get(session.getId() + "listeningDevices");
Map<String, String> allDevices = (Map<String, String>)Cache.get(session.getId() + "allDevices");
if(listeningDevices == null)
listeningDevices = new ArrayList<InetSocketAddress>();
if(allDevices == null)
allDevices = new TreeMap<String, String>();
renderScan(listeningDevices, allDevices);
}
Doing it this way results in Play doing some weird array copying that ends up taking infinite memory. If I were to change my call of showScan() to simply render() and create a view with the name networkScan.html, it all works just fine, no memory bugs.
I have several other methods that also use showScan, based on different caching settings. I don't want lots of views that are all essentially copies of each other, so I'm trying to go through just one method with one corresponding view.
This won't work:
showScan(listeningDevices, allDevices);
}
public static void showScan(List<InetSocketAddress> listeningDevices, Map<String, String> allDevices)
{
as play will serialize listeningDevices + allDevices to Strings and tries to build a url out of it.
either directly render the results in networkScan() or store the contents in the cache under a specific key
like you already do and then do something like
public static void networkScan(String networkTarget, String port)
{
//These two lists will never have more than 256 total entries
List<InetSocketAddress> listeningDevices;
Map<String, String> allDevices;
...Logic for discovering network devices...
//Store the results in a cache, for history preservation in the browser
Cache.set(session.getId() + "listeningDevices", listeningDevices);
Cache.set(session.getId() + "allDevices", allDevices);
showScan(session.getId());
}
public static void showScan(String sessionId)
{
List<InetSocketAddress> listeningDevices = Cache.get(sessionId + "listeningDevices");
Map<String, String> allDevices = Cache.get(sessionId + "allDevices");
render(listeningDevices, allDevices);
}
Turns out that calling an action method creates a redirect event, which resulted in all sorts of copying objects into URLs. I still don't understand how that mushroomed into using over a gigabyte of memory for a collection of Strings that rarely numbered above 100, and never above 256, but I found a way of avoiding the redirect event.
As I was directed to do in an answer on Google Groups, I made use of the #Util interceptor on the showScan method:
#Util
public static void showScan(List<InetSocketAddress> listeningDevices, Map<String, String> allDevices)
{
renderTemplate("Admin/showScan.html", listeningDevices, allDevices);
}
Marking a method with #Util unfortunately makes it use the template of the calling method, but the call to renderTemplate() allows me to use a single template that I specify.

Setting timeout for new URL(...).text in Groovy/Grails

I use the following Groovy snippet to obtain the plain-text representation of an HTML-page in a Grails application:
String str = new URL("http://www.example.com/some/path")?.text?.decodeHTML()
Now I want to alter the code so that the request will timeout after 5 seconds (resulting instr == null). What is the easiest and most Groovy way to achieve that?
I checked source code of groovy 2.1.8, below code is available:
'http://www.google.com'.toURL().getText([connectTimeout: 2000, readTimeout: 3000])
The logic to process configuration map is located in method org.codehaus.groovy.runtime.ResourceGroovyMethods#configuredInputStream
private static InputStream configuredInputStream(Map parameters, URL url) throws IOException {
final URLConnection connection = url.openConnection();
if (parameters != null) {
if (parameters.containsKey("connectTimeout")) {
connection.setConnectTimeout(DefaultGroovyMethods.asType(parameters.get("connectTimeout"), Integer.class));
}
if (parameters.containsKey("readTimeout")) {
connection.setReadTimeout(DefaultGroovyMethods.asType(parameters.get("readTimeout"), Integer.class));
}
if (parameters.containsKey("useCaches")) {
connection.setUseCaches(DefaultGroovyMethods.asType(parameters.get("useCaches"), Boolean.class));
}
if (parameters.containsKey("allowUserInteraction")) {
connection.setAllowUserInteraction(DefaultGroovyMethods.asType(parameters.get("allowUserInteraction"), Boolean.class));
}
if (parameters.containsKey("requestProperties")) {
#SuppressWarnings("unchecked")
Map<String, String> properties = (Map<String, String>) parameters.get("requestProperties");
for (Map.Entry<String, String> entry : properties.entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
}
}
return connection.getInputStream();
}
You'd have to do it the old way, getting a URLConnection, setting the timeout on that object, then reading in the data through a Reader
This would be a good thing to add to Groovy though (imho), as it's something I could see myself needing at some point ;-)
Maybe suggest it as a feature request on the JIRA?
I've added it as a RFE on the Groovy JIRA
https://issues.apache.org/jira/browse/GROOVY-3921
So hopefully we'll see it in a future version of Groovy...

Resources