Using setStrictHeaderValidationEnabled method in csvRoutines not working - csv

I am creating a bean processor and setting setStrictHeaderValidationEnabled to true. Now my CsvParserSettings are consuming this bean processor which in turn is consumed by CSVRoutines. But on iterating through csvroutines the bean processor does not validate headers and subsequent rows get converted to beans for files with invalid headers as well
Sample Code-
final BeanProcessor<TestBean> rowProcessor = new BeanProcessor<TestBean>(TestBean.class) {
#Override
public void beanProcessed(TestBean bean, ParsingContext context) {
}
};
rowProcessor.setStrictHeaderValidationEnabled(true);
final CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.setProcessor(rowProcessor);
parserSettings.setHeaderExtractionEnabled(true);
parserSettings.getFormat().setDelimiter(',');
CsvRoutines routines = new CsvRoutines(parserSettings);
for(TestBean bean : routines.iterate(TestBean.class, inputFile, StandardCharsets.UTF_8)) {
try {
System.out.println(OBJECT_MAPPER.writeValueAsString(bean));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
Note: TestBean uses #Parsed annotation of univocity to set column names.

The iterate method returns a IterableResult, which provides you the ParsingContext from which you can get the headers parsed from the input.
Try this code:
IterableResult<TestBean, ParsingContext> iterableResult = routines.iterate(TestBean.class, inputFile, StandardCharsets.UTF_8);
ResultIterator<TestBean, ParsingContext> iterator = iterableResult.iterator();
ParsingContext context = iterator.getContext();
String[] headers = context.headers();
//HEADERS HERE:
System.out.println(Arrays.toString(headers));
while(iterator.hasNext()){
try {
System.out.println(OBJECT_MAPPER.writeValueAsString(iterator.next()));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
Hope it helps

Related

How to bind class with constructor in Guice

I want to bind MyImpl to Multibinding. But MyImpl's constructor takes parameter.
final Multibinder<MyInterface> binder = Multibinder.newSetBinder(binder(), MyInterface.class)
binder.addBinding().to(MyImpl.class);
public MyImpl(Boolean myParam) ...
I do not want to #Inject it because it's say boolean, which can be occasionally injected somewhere else. So. I can introduce some Enum and inject it instead, how then to do this? Or can I better just write somehow
binder.addBinding().to(MyImpl.class, true);
binder.addBinding().to(MyImpl2.class, false);
or so?
I do not want to #Inject it because it's say boolean, which can be occasionally injected somewhere else.
To avoid this, use Named Annotations.
Solution One:
#Inject
public TextEditor(#Named("OpenOffice") SpellChecker spellChecker) { ...}
Here is the binding code:
bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice")).to(OpenOfficeWordSpellCheckerImpl.class);
Solution Two:
Load java-properties in a module and use the java-prop-names:
private static Properties loadProperties(String name){
Properties properties = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream(name);
try {
properties.load(is);
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if(is != null){
try {
is.close();
} catch (IOException dontCare) { }
}
}
return properties;
}
protected void configure() {
try{
Properties gameProperties = loadProperties("game.properties");
Names.bindProperties(binder(),gameProperties);
}catch (RuntimeException ex){
addError("Could not configure Game Properties");
};
}

Spying method calls the actual Method

I am writing a JUnit with Mockito. But on the line
when(encryptDecryptUtil.getKeyFromKeyStore(any(String.class))).thenReturn(keyMock);
It calls the actual method, which is causing the test failure. Interesting point is that it directly makes the actual call at start of the test case when when()...thenReturn() statemnts gets executed. Can you please tell me how I can fix this? My test is as per below
#Test
public void testDecryptData_Success() throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
encryptDecryptUtil = spy(new EncryptDecryptUtil());
Key keyMock = Mockito.mock(Key.class);
when(encryptDecryptUtil.getKeyFromKeyStore(any(String.class))).thenReturn(keyMock);
String inputData = "TestMessage";
String version = GetPropValues.getPropValue(PublisherConstants.KEYSTORE_VERSION);
byte[] enCryptedValue= new byte[] {9,2,5,8,9};
Cipher cipherMock = Mockito.mock(Cipher.class);
when(Cipher.getInstance(any(String.class))).thenReturn(cipherMock);
when(cipherMock.doFinal(any(byte[].class))).thenReturn(enCryptedValue);
String encryptedMessage = encryptDecryptUtil.encryptData(inputData);
assert(encryptedMessage.contains(version));
assertTrue(!encryptedMessage.contains(inputData));
}
On the third line it self, it calls the actual method.
Main code is as per below.
public class EncryptDecryptUtil {
private String publicKeyStoreFileName =
GetPropValues.getPropValue(PublisherConstants.KEYSTORE_PATH);
private String pubKeyStorePwd = "changeit";
private static final String SHA1PRNG = "SHA1PRNG";
private static final String pubKeyAlias="jceksaes";
private static final String JCEKS = "JCEKS";
private static final String AES_PADDING = "AES/CBC/PKCS5Padding";
private static final String AES = "AES";
private static final int CONST_16 = 16;
private static final int CONST_0 = 0;
private static final String KEY_STORE = "aes-keystore";
private static final String KEY_STORE_TYPE = "jck";
private static final Logger logger = Logger.getLogger(KafkaPublisher.class);
public Key getKeyFromKeyStore( String keystoreVersion) {
KeyStore keyStore = null;
Key key = null;
try {
keyStore = KeyStore.getInstance(JCEKS);
FileInputStream stream = null;
stream = new FileInputStream(publicKeyStoreFileName+KEY_STORE+PublisherConstants.UNDERSCORE+keystoreVersion+PublisherConstants.DOT+KEY_STORE_TYPE);
keyStore.load(stream, pubKeyStorePwd.toCharArray());
stream.close();
key = keyStore.getKey(pubKeyAlias, pubKeyStorePwd.toCharArray());
} catch (KeyStoreException e) {
e.printStackTrace();
}
catch (FileNotFoundException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (CertificateException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (IOException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
}
return key;
}
public String encryptData(String data) {
String keystoreVersion = GetPropValues.getPropValue(PublisherConstants.KEYSTORE_VERSION);
SecretKey secKey = new SecretKeySpec(getKeyFromKeyStore(keystoreVersion).getEncoded(), AES);
String base64EncodedEncryptedMsg = null;
Cipher cipher = null;
try { ------- Logic -------------------}
catch() { }
}
}
Have a look at the "Important gotcha on spying real objects" section of the Spy documentation.
Essentially, you cannot use the when(...).thenReturn(...) pattern with Spies, because as you have discovered, it calls the real method!
Instead, you use a different pattern which does exactly the same thing:
doReturn(...).when(spy).someMethod();
So, for your example:
doReturn(keyMock).when(encryptDecryptUtil).getKeyFromKeyStore(any(String.class));
Some advice which is unrelated to your question: If I read your code correctly, then EncryptDecryptUtil is the class that you are testing. As a general rule, you should not mock, stub, or spy on the object that you are actually testing, because then you are not testing the true object. You are actually testing a version of the object creating by the Mockito library. Furthermore, it's an uncommon pattern which will make your tests hard to read and maintain. If you find yourself having to do this, then the best thing would be to refactor your code so that the methods you are mocking (or spying on) and the methods you are testing are in different classes.

Webapi custom JsonMediaTypeFormatter

I am trying to create a custom JSONMediaTypeFormatter in which posts some json parameters to a webapi call. I need to encrypt the returned data from the webapi, hence writing a custom mediatypeformatter.
In my webapiconfig I clear all formatters and only add the custom formatter.
config.Formatters.Clear();
config.Formatters.Add(new CipherMediaFormatter());
In my custom media type formatter I add in the relevant headers and types but i still cant call my web api. It gives me an error
No MediaTypeFormatter is available to read an object of type 'Param' from content with media type 'application/json
The code for the mediatypeformatter
public class CipherMediaFormatter : JsonMediaTypeFormatter
{
private static Type _supportedType = typeof(object);
public CipherMediaFormatter()
{
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var taskSource = new TaskCompletionSource<object>();
try
{
var ms = new MemoryStream();
readStream.CopyTo(ms);
taskSource.SetResult(ms.ToArray());
}
catch (Exception e)
{
taskSource.SetException(e);
}
return taskSource.Task;
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var taskSource = new TaskCompletionSource<object>();
try
{
if (value != null)
{
var jsonData = JsonConvert.SerializeObject(value);
ICryptographicService cgService = new CryptographicService();
string apiKey = string.Empty;
string pattern = #"api\/(.*)?\/(\d+)?";
var match = Regex.Match(HttpContext.Current.Request.RawUrl, pattern);
....
}
}
catch (Exception e)
{
taskSource.SetException(e);
}
return taskSource.Task;
}
}
The problem was ReadFromStreamAsync causing the mediatypeformatter to error.

WebApi Custom MediaTypeFormatter get posted parameters

I am calling a post action on a webapi by passing in a serialised JSON DTO.
I also have a custom media type formatter to encrypt the resulting data. However in the WriteToStreamAsync method, how can i get the posted parameters?
The custom media type formatter class
public class JsonFormatter : JsonMediaTypeFormatter
{
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
var taskSource = new TaskCompletionSource<object>();
try
{
if (value != null)
{
//How to get posted parameters?
}
}
catch (Exception e)
{
taskSource.SetException(e);
}
return taskSource.Task;
}
}
}
I managed to get it via the HttpContext.Current.Request.InputStream
Using HttpContext.Current generally should not work in this scenario since it won't always be available for async calls.
Instead do something like this:
public class JsonFormatter : JsonMediaTypeFormatter
{
private readonly HttpRequestMessage request;
public JsonFormatter() { }
public JsonFormatter(HttpRequestMessage request)
{
this.request = request;
}
public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, MediaTypeHeaderValue mediaType)
{
return new JsonFormatter(request);
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
// logic referencing this.request
}
}

Handle Stream in Custom URI Resolver for Saxon Parser

I have to process an xml against an xslt with result-document that create many xml.
As suggested here:
Catch output stream of xsl result-document
I wrote my personal URI Resolver:
public class CustomOutputURIResolver implements OutputURIResolver{
private File directoryOut;
public CustomOutputURIResolver(File directoryOut) {
super();
this.directoryOut = directoryOut;
}
public void close(Result arg0) throws TransformerException {
}
public Result resolve(String href, String base) throws TransformerException {
FileOutputStream fout = null;
try {
File f = new File(directoryOut.getAbsolutePath() + File.separator + href + File.separator + href + ".xml");
f.getParentFile().mkdirs();
fout = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return new StreamResult(fout);
}
}
that get the output directory and then saves here the files.
But then when I tested it in a junit I had some problems in the clean-up phase, when trying to delete the created files and noticed that the FileOutputStream fout is not well handled.
Trying to solve the problem gave me some thoughts:
First I came out with this idea:
public class CustomOutputURIResolver implements OutputURIResolver{
private File directoryOut;
private FileOutputStream fout
public CustomOutputURIResolver(File directoryOut) {
super();
this.directoryOut = directoryOut;
this.fout = null;
}
public void close(Result arg0) throws TransformerException {
try {
if (null != fout) {
fout.flush();
fout.close();
fout = null;
}
} catch (Exception e) {}
}
public Result resolve(String href, String base) throws TransformerException {
try {
if (null != fout) {
fout.flush();
fout.close();
}
} catch (Exception e) {}
fout = null;
try {
File f = new File(directoryOut.getAbsolutePath() + File.separator + href + File.separator + href + ".xml");
f.getParentFile().mkdirs();
fout = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return new StreamResult(fout);
}
}
So the fileOutputStream is closed anytime another one is opened.
But:
1) I don't like this solution very much
2) what if this function is called in a multithread process? (I'm not very skilled about Saxon parsing, so i really don't know..)
3) Is there a chance to create and handle one FileOutputStream for each resolve ?
The reason close() takes a Result argument is so that you can identify which stream to close. Why not:
public void close(Result arg0) throws TransformerException {
try {
if (arg0 instanceof StreamResult) {
OutputStream os = ((StreamResult)arg0).getOutputStream();
os.flush();
os.close();
}
} catch (Exception e) {}
}
From Saxon-EE 9.5, xsl:result-document executes in a new thread, so it's very important that the OutputURIResolver should be thread-safe. Because of this change, from 9.5 an OutputURIResolver must implement an additional method getInstance() which makes it easier to manage state: if your newInstance() method actually creates a new instance, then there will be one instance of the OutputURIResolver for each result document being processed, and it can hold the output stream and close it when requested.