Custom Navigable Actuator Endpoint in SpringBoot2 - spring-boot-actuator

I have written a Spring-Boot version 2, Custom Endpoint actuator code and trying to make it navigable using #Selector option,
1) when I enter the URL http://localhost/actuator/notes/1.0 in the browser, its giving me 400 as error code and the expected output should be ** Version 1.0 **
2) when I enter the URL http://localhost/actuator/notes in the browser, its giving me expected output which is
** Version 1.1 ** ** Version 1.0 **
#Component
#Endpoint(id="notes")
public class NotesEndPoint {
String notesOne=" ** Version 1.0 ** ";
String notesTwo = "** Version 1.1 **";
#ReadOperation
public String selectNotes(#Selector String selector ) {
if("1.0".equals(selector)) return notesOne ;
else if("1.1".equals(selector)) return notesTwo ;
else return getNotesVersion();
}
#ReadOperation
public String getNotesVersion(){
return notesTwo + notesOne;
}
}

Related

ConvertApi NuGet Package Error: Could not install package 'ConvertApi 2.7.0'

I am Adding ConvertApi nuget package to Convert PDF to Doc file,
But getting below Error
Could not install package 'ConvertApi 2.7.0'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.6.1', but the package does not contain any assembly references or content files that are compatible with that framework.
Note:
You can Suggesst some other API's as well to achieve the above task.
The ConvertApi 2.7.0 NuGet package is .NET Core 2 version library and can be installed on .NET 4.7 or higher. However, you can use plain C# implementation to call ConvertAPI REST API, the example below use WebClient to send an MS Word file for conversion to PDF document.
using System;
using System.Net;
using System.IO;
class MainClass {
public static void Main (string[] args) {
const string fileToConvert = "test.docx";
const string fileToSave = "test.pdf";
const string Secret="";
if (string.IsNullOrEmpty(Secret))
Console.WriteLine("The secret is missing, get one for free at https://www.convertapi.com/a");
else
try
{
Console.WriteLine("Please wait, converting!");
using (var client = new WebClient())
{
client.Headers.Add("accept", "application/octet-stream");
var resultFile = client.UploadFile(new Uri("http://v2.convertapi.com/convert/docx/to/pdf?Secret=" + Secret), fileToConvert);
File.WriteAllBytes(fileToSave, resultFile );
Console.WriteLine("File converted successfully");
}
}
catch (WebException e)
{
Console.WriteLine("Status Code : {0}", ((HttpWebResponse)e.Response).StatusCode);
Console.WriteLine("Status Description : {0}", ((HttpWebResponse)e.Response).StatusDescription);
Console.WriteLine("Body : {0}", new StreamReader(e.Response.GetResponseStream()).ReadToEnd());
}
}
}

Need to write WARNING Level logs to different file using filehandler but console handler still show INFO and SEVERE but NO WARNING when .level=INFO

We have a Java application on Websphere where we need SystemOut.log only print loglevel SEVERE and INFO (using existing java.util.logging default ConsoleHandler), but we need a WARNING written to separate file using the FileHandler .
Created a LevelBasedFileHandler which takes log level and file to write and i can see the log file updated as needed.
But the Warning level's are written in SystemOut.log too, Need a way to stop them from appearing
logger.addHandler(new LevelBasedFileHandler("../logs/warning.log", Level.WARNING));
logger.setFilter(new LevelBasedFilter()); - Trying to see if i can filter
logger.setUseParentHandlers(false);
using the logger.setUseParentHandlers(false) is not printing any information to SystemOut.log if i remove it i see WARNING information too. Any idea i can filter the Warning Level from this?
If you filter at the logger level that will suppress log records before they reach any of the handlers. What you should do is install filters on the existing handlers.
For example, create a filter which takes a boolean:
import java.util.logging.Filter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
public class WarningFilter implements Filter {
private final boolean complement;
public WarningFilter(final boolean complement) {
this.complement = complement;
}
#Override
public boolean isLoggable(LogRecord r) {
return Level.WARNING.equals(r.getLevel()) != complement;
}
}
Next you should install your filter on each handler. For example:
private static final Logger logger = Logger.getLogger("some.other.logger.name");
public static void main(String[] args) throws Exception {
boolean found = false;
for (Handler h : Logger.getLogger("").getHandlers()) {
h.setFilter(new WarningFilter(h instanceof ConsoleHandler));
}
if(!found) {
Handler h = new ConsoleHandler();
h.setFilter(new WarningFilter(true));
}
Handler h = new FileHandler();
h.setFilter(new WarningFilter(false));
logger.addHandler(h);
}

flyway - The meaning of the concept of checksums

I'm learning Flyway migration tool, and I don't have clear the concept of checksums. Could someone explain me what is? how is it calculated, or how can it be changed?
I understand the repair command re-calculate the checksum, I do not understand how it differs.
Thanks!
Checksum field in Flyway forming a part of verification mechanism ensuring that migration scripts haven't been changed since they applied to the database. This will guaranty that all instances of your application will have same database structure (content). You can switch off verification, but I will not recommend you to do so. Answering you questions:
What is?
Just google what is checksum. Wikipedia
How is it calculated?
For SQL migrations Flyway uses CRC32 class to calculate the checksum. For exact code see below.
How can it be changed?
The checksum of the migration will be changed once the binary content of you migration modified. If you want to change checksum field in the DB when you need to calculate the checksum for the new version of your migration file and then change the value in the DB. However, I wouldn't recommend to do that. You shouldn't need to do that and the fact that you want to change it may indicate that you doing something wrong. Anyway, the calculation code for the checksum is quite simple (with courtesy of Flyway source code):
/**
* Calculates the checksum of this string.
*
* #param str The string to calculate the checksum for.
* #return The crc-32 checksum of the bytes.
*/
/* private -> for testing */
static int calculateChecksum(Resource resource, String str) {
final CRC32 crc32 = new CRC32();
BufferedReader bufferedReader = new BufferedReader(new StringReader(str));
try {
String line;
while ((line = bufferedReader.readLine()) != null) {
crc32.update(line.getBytes("UTF-8"));
}
} catch (IOException e) {
String message = "Unable to calculate checksum";
if (resource != null) {
message += " for " + resource.getLocation() + " (" + resource.getLocationOnDisk() + ")";
}
throw new FlywayException(message, e);
}
return (int) crc32.getValue();
}
To calculate flyway checksum for arbitrary file, I use the following code:
import java.util.*;
import org.flywaydb.core.internal.resource.filesystem.*;
import org.flywaydb.core.internal.resolver.*;
import java.nio.charset.*;
public class Program {
public static void main( String[] args ) throws Exception{
String filename="/path/to/migration/V8_test.sql";
FileSystemResource r = new FileSystemResource(null, filename,Charset.forName("UTF-8"));
int cs = ChecksumCalculator.calculate(r);
System.out.println(cs);
}
}
Only dependency for this code is org.flywaydb:flyway-core:6.4.1
For version 8.10 #Eugene's answer needs to change a bit:
get_flyway_checksum.java:
import java.util.*;
import org.flywaydb.core.internal.resource.filesystem.*;
import org.flywaydb.core.internal.resolver.*;
import org.flywaydb.core.internal.resource.*;
import org.flywaydb.core.api.Location;
import java.nio.charset.*;
public class Program {
public static void main( String[] args ) throws Exception{
Location loc = null;
String filepath = args[0];
FileSystemResource r = new FileSystemResource(loc, filepath,Charset.forName("UTF-8"), false);
int cs = ChecksumCalculator.calculate(r);
System.out.println(cs);
}
}
To get the checksum:
java -cp {path to your flyway installation}/lib/community/flyway-core-8.1.0.jar get_flyway_checksum.java {filepath}

Run Rscript from Spring MVC with Wildfly 9

I am trying to run Rscript from JAVA code. I am able to do so. Now I am trying to run same JAVA code from a Spring MVC project and using Wildfly 9 to run the project. For the first time when I am trying to execute JAVA code (to run Rscript) is working fine and giving correct result, but on running 2nd time it is giving error and Wildfly stops running. Below is the error that I am getting:
A fatal error has been detected by the Java Runtime Environment:
Internal Error (0xc0000029), pid=6768, tid=8456
JRE version: Java(TM) SE Runtime Environment (7.0_75-b13) (build 1.7.0_75-b13)
Java VM: Java HotSpot(TM) Client VM (24.75-b04 mixed mode, sharing windows-x86 )
Problematic frame:
C [ntdll.dll+0xa096a]
Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
The JAVA code is below:
package com.test.util;
import org.rosuda.JRI.Rengine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RunRScript {
private static final Logger logger = LoggerFactory
.getLogger(RunRScript.class);
public void runScript() {
// Create an R vector in the form of a string.
String javaVector = "c(1,2,3,4,5)";
// Start Rengine.
Rengine engine = new Rengine(new String[] { "--no-save" }, false, null);
// The vector that was created in JAVA context is stored in 'rVector' which is a variable in R context.
engine.eval("rVector=" + javaVector);
//Calculate MEAN of vector using R syntax.
engine.eval("meanVal=mean(rVector)");
//Retrieve MEAN value
double mean = engine.eval("meanVal").asDouble();
//Print output values
logger.info("Mean of given vector is=" + mean);
}
}
I am using Windows 8 64-bit and R-2.15.0. Please let me know if my question is not clear or you need any other information. Thanks in advance.
You can't call JRI engine with that code. According to the documentation, JRI doesn't allow more that one engine instance per JVM, so you shouldn't create more than one engine.
This line:
// Start Rengine.
Rengine engine = new Rengine(new String[] { "--no-save" }, false, null);
Must be called only once. You have to ensure that only one engine is started in your JVM.
On the other hand, JRI uses by default the same environment to handle all the calls (eval, assign, etc...) so the rest of your code must be synchronized, otherwise you can suffer race conditions every time two different threads are executing eval methods.
If you have trouble getting it working, you can replace JRI by Rserve, that doesn't need JRI library loaded into the JVM and allow concurrency (each thread must use its own RConnection).
But with Rserve you should setup your engine only once, as well as using JRI.
You can use a #PostConstruct method:
/**
* This method initializes REngine properly and make all the operations needed
* to set up the environment.
*
* This RServe implementation must run R in a separate process and check the connection.
*
*/
#PostConstruct
public void setUpR() {//NOSONAR
REngine engine = null;
try {
if(LOGGER.isInfoEnabled()) {
LOGGER.info("Starting RServe process...");
}
ProcessBuilder builder = new ProcessBuilder("/bin/sh", "-c", String.format("echo 'library(Rserve);Rserve(FALSE,args=\"--no-save --slave --RS-conf %s\")'|%s --no-save --slave", rserveConf, rexe));
builder.inheritIO();
Process rProcess = builder.start();
if(LOGGER.isInfoEnabled()) {
LOGGER.info("Waiting for Rserve to start...");
}
int execCodeResult = rProcess.waitFor();
if(execCodeResult != SUCCESS_CODE) {
LOGGER.error(String.format("Unexpected error code starting RServe: %d", execCodeResult));
} else {
LOGGER.error("RServe started successfully");
}
if(LOGGER.isInfoEnabled()) {
LOGGER.info("Opening connection to RServe daemon....");
}
engine = new RConnection();
if(LOGGER.isInfoEnabled()) {
LOGGER.info(String.format("Obtaining R server version: %d", ((RConnection)engine).getServerVersion()));
}
} catch(Exception e) {
LOGGER.error("Unexpected error setting up RServe environment", e);
} finally {
closeRServeConnection(engine);
}
}
You can do the same with JRI:
/**
* This method initializes REngine properly and make all the operations needed
* to set up the environment.
*
* This JRI implementation must load JRI library and starts JRIEngine
*
*/
#PostConstruct
public void setUpR() {//NOSONAR
try {
//make sure JRI lib can be loaded (it must be present in java.library.path parameter)
//This line is necessary because Rengine.versionCheck() will execute a System.exit if
//it can't load JRI library.
System.loadLibrary("jri");
// just making sure we have the right version of everything
if (!Rengine.versionCheck()) {
LOGGER.error("** Version mismatch - Java files don't match library version.");
LOGGER.error(String.format("Invalid versions. Rengine must have the same version of native library. Rengine version: %d. RNI library version: %d", Rengine.getVersion(), Rengine.rniGetVersion()));
}
// Enables debug traces
Rengine.DEBUG = 1;
if(LOGGER.isInfoEnabled()) {
LOGGER.info("Creating Rengine (with arguments)");
}
// 1) we pass the arguments from the command line
// 2) we won't use the main loop at first, we'll start it later
// (that's the "false" as second argument)
// 3) no callback class will be used
this.engine = REngine.engineForClass("org.rosuda.REngine.JRI.JRIEngine", new String[] { "--no-save" }, new REngineStdOutCallback(LOGGER), false);
if(LOGGER.isInfoEnabled()) {
LOGGER.info("Rengine created...");
LOGGER.info("Loading blockFunction from " + getBlockFunction());
}
REXP result = engine.parseAndEval(getBlockFunction());
if(result == null) {
LOGGER.error("blockFunction is not loaded!");
} else if(LOGGER.isInfoEnabled()) {
LOGGER.info("blockFunction loaded successfully");
}
} catch(Exception|UnsatisfiedLinkError e) {
LOGGER.error("Unexpected error setting up R", e);
}
}
And then reuse the same Rengine instance in each call (make sure you synchronize the access to this instance).
You have more examples in this repo

How to exit an air application from an actionscript library?

I am trying the following but every once in awhile the nativeApp is not defined.
var nativeApp:Object = getDefinitionByName("flash.desktop.NativeApplication");
nativeApp.nativeApplication.exit();
I am confused why sometimes getDefinitionByName("flash.desktop.NativeApplication") resolves and other times it does not.
I am trying to resolve this problem to address the following issue in flexcover - code.google.com/p/flexcover/issues/detail?id=33
Update - here is the class I am attempting to fix: http://code.google.com/p/flexcover/source/browse/trunk/CoverageAgent/src/com/allurent/coverage/runtime/AbstractCoverageAgent.as CoverageAgent.swc is an actionscript library called by the unit tests to exit the flexcover air application used to determine the code coverage of the unit tests. The flexcover air application only exits about the half the time and it is causing problems for our maven builds to execute successfully.
NativeApplication.nativeApplication.exit();
In regards to FlexCover - the reason you are seeing it work sometimes and not others is the CoverageAgent is designed to exit the Unit Tests it does not communicate back to the CoverageViewer. I have created my own FlexCoverListener that sends an exit message over local connection to the CoverageViewer. Below is the code.
package org.flexunit.listeners
{
import flash.events.EventDispatcher;
import org.flexunit.listeners.closer.FlexCoverCloser;
import org.flexunit.runner.IDescription;
import org.flexunit.runner.Result;
import org.flexunit.runner.notification.Failure;
import org.flexunit.runner.notification.IAsyncStartupRunListener;
import org.flexunit.runner.notification.ITemporalRunListener;
public class FlexCoverListener extends EventDispatcher implements IAsyncStartupRunListener,
ITemporalRunListener
{
import com.allurent.coverage.runtime.CoverageManager;
public function FlexCoverListener()
{
}
public function get ready():Boolean
{
return true;
}
public function testTimed( description:IDescription, runTime:Number ):void
{
}
public function testRunFinished( result:Result ):void
{
CoverageManager.agent.recordCoverage("SR_TESTS_COMPLETE");
}
public function testFinished( description:IDescription ):void {}
public function testRunStarted( description:IDescription ):void {}
public function testStarted( description:IDescription ):void{}
public function testFailure( failure:Failure ):void{}
public function testAssumptionFailure( failure:Failure ):void{}
public function testIgnored( description:IDescription ):void{}
}
}
You can add the above listener to your tests by doing the following in your TestRunner:
core.addListener(new FlexCoverListener());
var core : FlexUnitCore = new FlexUnitCore();
Last but most importantly I changed the recordCoverage method in the AbstractCoverageAgent to look like the following:
/**
* Record the execution of a single coverage key; called by
* the global coverage() function.
*/
public function recordCoverage(key:String):void
{
if(key == "SR_TESTS_COMPLETE")
{
exit();
}
else if (isNaN(coverageMap[key]++))
{
// The map must not have contained this key yet, so enter an
// execution count of 1. Subsequent calls will autoincrement without
// returning NaN.
//
coverageMap[key] = 1;
}
}
nativeAppilcation is a static field. It does not need to be called on an object. So you do not have to call getDefinitionByName("flash.desktop.NativeApplication").
Just invoke exit as follows:
NativeApplication.nativeApplication.exit();
Flash Builder or Flash Pro will include the library for you.
If you are not using the IDE, import the library:
import flash.desktop.NativeApplication;

Resources