read json file from resources - quarkus

I'm trying to read json file that located in documents folder into resources file in quarkus.
here is my code:
try(InputStream inputStream = classLoader.getResourceAsStream("documents/helloWorldDocument.json")) {
// Retrieve the JSON document and put into a string/object map
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> documentMapType =
new TypeReference<HashMap<String, Object>>() {};
//
Map<String, Object> document = mapper.readValue(
new File(inputStream.toString()),
documentMapType);
// Use builder methods in the SDK to create the directive.
RenderDocumentDirective renderDocumentDirective = RenderDocumentDirective.builder()
.withToken("helloWorldToken")
.withDocument(document)
.build();
// Add the directive to a responseBuilder.
responseBuilder.addDirective(renderDocumentDirective);
// Tailor the speech for a device with a screen.
speechText.append(" You should now also see my greeting on the screen.");
} catch (IOException e) {
throw new AskSdkException("Unable to read or deserialize the hello world document", e);
}
but getting exception. really appreciate if anyone could help.
(I'm implementing APL for an alexa skill)

After searching a lot, I solve this:
try {
File file = new File(
Objects.requireNonNull(this.getClass().getClassLoader().getResource("helloWorldDocument.json")).getFile()
);
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> documentMapType =
new TypeReference<HashMap<String, Object>>() {
};
Map<String, Object> document = mapper.readValue(
new File(file.toString()),
documentMapType);
RenderDocumentDirective renderDocumentDirective = RenderDocumentDirective.builder()
.withToken("helloWorldToken")
.withDocument(document)
.build();
responseBuilder.addDirective(renderDocumentDirective);
speechText.append(" You should now also see my greeting on the screen.");
} catch (IOException e) {
throw new AskSdkException("Unable to read or deserialize the hello world document", e);
}

Related

"For an upload InputStream with no MD5 digest metadata, the markSupported() method must evaluate to true." in Spring Integration AWS

UPDATE: There is bug in spring-integration-aws-2.3.4
I am integrating SFTP (SftpStreamingMessageSource) as source with S3 as destination.
I have similar Spring Integration configuration:
#Bean
public S3MessageHandler.UploadMetadataProvider uploadMetadataProvider() {
return (metadata, message) -> {
if ( message.getPayload() instanceof DigestInputStream) {
metadata.setContentType( MediaType.APPLICATION_JSON_VALUE );
// can not read stream to manually compute MD5
// metadata.setContentMD5("BLABLA==");
// this is wrong approach: metadata.setContentMD5(BinaryUtils.toBase64((((DigestInputStream) message.getPayload()).getMessageDigest().digest()));
}
};
}
#Bean
#InboundChannelAdapter(channel = "ftpStream")
public MessageSource<InputStream> ftpSource(SftpRemoteFileTemplate template) {
SftpStreamingMessageSource messageSource = new SftpStreamingMessageSource(template);
messageSource.setRemoteDirectory("foo");
messageSource.setFilter(new AcceptAllFileListFilter<>());
messageSource.setMaxFetchSize(1);
messageSource.setLoggingEnabled(true);
messageSource.setCountsEnabled(true);
return messageSource;
}
...
#Bean
#ServiceActivator(inputChannel = "ftpStream")
public MessageHandler s3MessageHandler(AmazonS3 amazonS3, S3MessageHandler.UploadMetadataProvider uploadMetadataProvider) {
S3MessageHandler messageHandler = new S3MessageHandler(amazonS3, "bucketName");
messageHandler.setLoggingEnabled(true);
messageHandler.setCountsEnabled(true);
messageHandler.setCommand(S3MessageHandler.Command.UPLOAD);
messageHandler.setUploadMetadataProvider(uploadMetadataProvider);
messageHandler.setKeyExpression(new ValueExpression<>("key"));
return messageHandler;
}
After start, I am getting following error
"For an upload InputStream with no MD5 digest metadata, the markSupported() method must evaluate to true."
This is because ftpSource is producing InputStream payload without mark/reset support. I even tried to transform InputStream to BufferedInputStream using #Transformer e.g. following
return new BufferedInputStream((InputStream) message.getPayload());
and no success, because then I am getting message "java.io.IOException: Stream closed" because S3MessageHandler:338 is calling Md5Utils.md5AsBase64(inputStream) which closes stream too early.
How to generate MD5 for all messages in Spring Integration AWS without pain?
I am using spring-integration-aws-2.3.4.RELEASE
The S3MessageHandler does this:
if (payload instanceof InputStream) {
InputStream inputStream = (InputStream) payload;
if (metadata.getContentMD5() == null) {
Assert.state(inputStream.markSupported(),
"For an upload InputStream with no MD5 digest metadata, "
+ "the markSupported() method must evaluate to true.");
String contentMd5 = Md5Utils.md5AsBase64(inputStream);
metadata.setContentMD5(contentMd5);
inputStream.reset();
}
putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata);
}
Where that Md5Utils.md5AsBase64() closes an InputStream in the end - bad for us.
This is an omission on our side. Please, raise a GH issue and we will fix it ASAP. Or feel free to provide a contribution.
As a workaround I would suggest to have a transformer upfront of this S3MessageHandler with the code like:
return org.springframework.util.StreamUtils.copyToByteArray(inputStream);
This way you will have already a byte[] as a payload for the S3MessageHandler which will use a different branch for processing:
else if (payload instanceof byte[]) {
byte[] payloadBytes = (byte[]) payload;
InputStream inputStream = new ByteArrayInputStream(payloadBytes);
if (metadata.getContentMD5() == null) {
String contentMd5 = Md5Utils.md5AsBase64(inputStream);
metadata.setContentMD5(contentMd5);
inputStream.reset();
}
if (metadata.getContentLength() == 0) {
metadata.setContentLength(payloadBytes.length);
}
putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, metadata);
}

Unit test in Spring boot using Mockito

While executing Juint4 test. it shows null pointer exception. while using save method in unit test it returns null. Here i am using Mockito Juint4 Testing to mock the method. someone help me out with this.
**Service Method.**
public Result save(Map inputParams){
Result result = new Result();
logger.info("::::::::::::::: save ::::::::::::::::"+inputParams);
try{
String name = inputParams.get("name").toString();
String type = inputParams.get("type").toString();
CoreIndustry coreIndustry = coreIndustryDao.findByName(name);
if(coreIndustry != null){
result.setStatusCode(HttpStatus.FOUND.value());
result.setMessage(Messages.NAME_EXIST_MESSAGE);
result.setSuccess(false);
}else{
CoreIndustry coreIndustryNew = new CoreIndustry();
coreIndustryNew.setName(name);
coreIndustryNew.setType(type);
coreIndustryNew.setInfo(new Gson().toJson(inputParams.get("info")));
System.out.println("CoreIndustry Info is :............:.............:..............:"+coreIndustryNew.getInfo());
CoreIndustry coreIndustryData = coreIndustryDao.save(coreIndustryNew);
System.out.println("Saved Data Is.............::::::::::::::::::::................ "+coreIndustryData.getName()+" "+coreIndustryData.getType()+" "+coreIndustryData.getType());
result.setData(coreIndustryData);
result.setStatusCode(HttpStatus.OK.value());
result.setMessage(Messages.CREATE_MESSAGE);
result.setSuccess(true);
}
}catch (Exception e){
logger.error("::::::::::::::: Exception ::::::::::::::::"+e.getMessage());
result.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
result.setSuccess(false);
result.setMessage(e.getMessage());
}
return result;
}
**Controller**
#PostMapping(path = "/industry/save")
public Result save(#RequestBody Map<String, Object> stringToParse) {
logger.debug("save---------------"+stringToParse);
Result result = industryService.save(stringToParse);
return result;
}
**Unit Test**
#RunWith(SpringRunner.class)
#SpringBootTest
public class IndustryServiceTest {
#MockBean
private CoreIndustryDao coreIndustryDao;
private IndustryService industryService;
#Test
public void getAll() {
System.out.println("::::::: Inside of GetAll Method of Controller.");
// when(coreIndustryDao.findAll()).thenReturn(Stream.of(
// new CoreIndustry("Dilip","Brik","Brik Industry"))
// .collect(Collectors.toList()));
//assertEquals(1,industryService.getAll().setData());
}
#Test
public void save() {
ObjectMapper oMapper = new ObjectMapper();
CoreIndustry coreIndustry = new CoreIndustry();
coreIndustry.setId(2L);
coreIndustry.setName("Dilip");
coreIndustry.setType("Business");
HashMap<String,Object> map = new HashMap();
map.put("name","Retail");
map.put("type","Development");
coreIndustry.setInfo(new Gson().toJson(map));
when(coreIndustryDao.save(any(CoreIndustry.class))).thenReturn(new CoreIndustry());
Map<String, Object> actualValues = oMapper.convertValue(coreIndustry,Map.class);
System.out.println("CoreIndustry Filed values are........ : "+coreIndustry.getName()+" "+coreIndustry.getInfo());
Result created = industryService.save(actualValues);
CoreIndustry coreIndustryValue = (CoreIndustry) created.getData();
Map<String, Object> expectedValues = oMapper.convertValue(coreIndustryValue, Map.class);
System.out.println(" Getting Saved data from CoreIndustry........"+expectedValues);
System.out.println(" Getting Saved data from CoreIndustry........"+coreIndustryValue.getName());
assertThat(actualValues).isSameAs(expectedValues);
}
I am new in this Spring boot Technology.
After Running the source code for save method.
After Debugging my source code..
It will be great please to help me out. Thank you.

Parse a JSONNode using Java 8 stream API

I'm reading all Objects from Salesforce environment using Java, it's working fine but below code is taking 10 mins to convert the JSON into Java ArrayList. I was thinking if I can use Java - 8 stream API to parallel the parsing logic. Below is my working code, any suggestion appreciated.
/**
* #Desc : Get All available objects(tables) from salesforce
* #return : List<SalesforceObject>
* */
public List<SalesforceObject> getAllsObjects() {
List<SalesforceObject> listsObject = new ArrayList<SalesforceObject>();
try {
// query Salesforce
final URIBuilder builder = new URIBuilder(this.sfAccess.instanceURL);
builder.setPath(appProp.salesforceObjectPath);
final HttpGet get = new HttpGet(builder.build());
get.setHeader("Authorization", "Bearer " + this.sfAccess.token);
final CloseableHttpClient httpclient = HttpClients.createDefault();
final HttpResponse queryResponse = httpclient.execute(get);
// parse
final ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
final JsonNode queryResults = mapper.readValue(queryResponse.getEntity().getContent(), JsonNode.class);
System.out.println(queryResults);
// This line takes - 10 mins
listsObject.addAll(mapper.convertValue(queryResults.get("sobjects"), new TypeReference<List<SalesforceObject>>(){}));
return listsObject;
} catch(IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
You are looking at,
return StreamSupport.stream(queryResults.get("sobjects").spliterator(), true)
.map(sObj -> mapper.convertValue(sObj, SalesforceObject.class))
.collect(Collectors.toList());
Note that your concurrency will still be limited by the number of CPU cores of your server.

Veracode CWE id 611

I have a piece of code where there is veracode finding for Improper Restriction of XML External Entity Reference ('XXE') Attack.
Code:
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(node);
transformer.transform(source, result); //CWE ID 611, impacted line.
I used
transformer.setOutputProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transformer.setOutputProperty(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
but no luck.
The issue got resolved with the following code:
TransformerFactory transformer = TransformerFactory.newInstance();//.newTransformer();
transformer.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transformer.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(node);
transformer.newTransformer().transform(source, result);
It is advised to put a try-catch block.
try{
transformer.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transformer.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
} catch (IllegalArgumentException e) {
//jaxp 1.5 feature not supported
}
Please note for anyone running the application on JDK5 or older that you will not have these XML Constants available:
transformer.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
transformer.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
Instead you will have to parse to a Document using a secured document builder then use a DOM source in your transformer.
private static void example(String xmlDocument, Result result) throws ParserConfigurationException, IOException, SAXException, TransformerException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String s, String s1) throws SAXException, IOException {
return new InputSource(new StringReader(""));
}
});
Document doc = db.parse(new InputSource(new StringReader(xmlDocument)));
DOMSource domSource = new DOMSource(doc);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(domSource, result);
}

Reading property file in Spring MVC app

I'm trying to read a property file using below code, basically I'm having a Spring Boot app and I'm trying to read the below non spring bean class.The property file is in src/main/resource directory.
public class VisaProperties {
static Properties properties;
static {
try {
properties = new Properties();
String propertiesFile = System.getProperty("ftproperties");
if (propertiesFile == null) {
properties.load(VisaProperties.class.getResourceAsStream("motoconfig.cybersource.properties"));
} else {
properties.load(new FileReader(propertiesFile));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String getProperty(Property property) {
return (String) properties.get(property.getValue());
}
}
and trying call the end point property using below code getting null. How can I call the property?
VisaProperties.getProperty(Property.END_POINT)
You can simplify the code as:
final Properties properties = new Properties();
try (final InputStream stream =
this.getClass().getResourceAsStream("config.properties")) {
properties.load(stream);
}
Note: Use "try with resources" so that stream will be automatically
closed when the try {} block exits.
Done, using the code below:
Properties properties = new Properties();
InputStream inputStream = VisaProperties.class
.getClassLoader()
.getResourceAsStream("config.properties");
properties.load(inputStream);
inputStream.close();

Resources