I need to zip a payload (a dataweave script outputting CSV) with a password using Mule 4 with encryption AES256.
I've checked the Compression Module of Mule 4 and it doesnt support passwords, I've tried using it in combination of the Cryptography Module but it either ends up encrypting the CSV in the zip, or encrypting the zip.
I need the solution to be able to run in Cloudhub too.
Any ideas?
Cheers,
Steve
Just encrypting the files will not work because the Zip format expects an encryption header for encrypted files.
Mule Compression module uses the Apache Commons Compress library to implement Zip files, which doesn't currently support Zip encrypted files.
You can try to either implement your own module or extend the existing Compression module to support encryption. You can also just call a Java class to do it, but it will not be as reusable in Mule applications.
One library that can be used to implement encrypted Zip files is Zip4j but there might be others. Since it is a Java implementation it should work in any platform.
My solution:
<java:invoke-static doc:name="Invoke static" doc:id="6244c876-c938-4541-a8aa-a94d2198aa28" class="au.com.test.PasswordProtectedZip" method="zip(String, String)">
<java:args ><![CDATA[#[{
"fileName": p('file.path') ++ vars.fileName,
"password": p('secure::encryption.password')
}]]]></java:args>
</java:invoke-static>
The Java Class:
package au.com.test;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.EncryptionMethod;
public class PasswordProtectedZip {
public static File zip(String fileName, String password) {
System.out.println("Zipping " + fileName);
File file = null;
try {
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
List<File> filesToAdd = Arrays.asList(new File(fileName));
ZipFile zipFile = new ZipFile(fileName + ".zip", password.toCharArray());
zipFile.addFiles(filesToAdd, zipParameters);
file = zipFile.getFile();
System.out.println("file = " + file.getAbsolutePath());
zipFile.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
}
And the deps in the pom.xml:
<dependency>
<groupId>net.lingala.zip4j</groupId>
<artifactId>zip4j</artifactId>
<version>1.3.1</version>
</dependency>
Related
I have a requirement where in I need to download couple of files (done using karate feature file) and move them to a specific folder (done using java and calling it in the feature file).
In between that I need to check if all the expected files are downloaded. So what I was thinking is, if there is a way to generate report before moving them to the specific folder. So from the report I can come to know if it has passed or failed.
I have the code for generating cucumber report in the runner class and i tried to use the below in the feature file and it does not run.. Gives an error
* def report = Java.type('BI.BiTestRunner')
* def result3 = report.generateReport()
Error:
BI.BiTestRunner failed due to: Arity error - expected: 1 actual: 0
Code in my runner class
package BI;
import com.intuit.karate.Results;
import com.intuit.karate.Runner;
import net.masterthought.cucumber.Configuration;
import net.masterthought.cucumber.ReportBuilder;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.junit.Assert.assertTrue;
public class BiTestRunner {
#Test
public void testParallel() {
System.setProperty("karate.env", "BI");
Results results = Runner.path("classpath:BI/Fluent.feature").outputCucumberJson(true).tags("~#ignore").parallel(1);
generateReport(results.getReportDir());
assertTrue(results.getErrorMessages(), results.getFailCount() == 0);
}
public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[]{"json"}, true);
List<String> jsonPaths = new ArrayList(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "qa-automation");
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
}
Can someone help me on this please?
No, you can't do this. Until Karate completes, the files needed for generateReport() will not even exist.
This will require some advanced Java - and you can refer the section in this guide with the title "Retry Framework".
With some custom Java code you should be able to take any failed tests at the end of a Runner invocation and re-try them, and merge the results back into the final aggregated report. See example code.
If the above does not help, please consider this as not supported by Karate.
#Vishnuprya k I know this is a pretty old topic, but I managed to make the generateReport working as expected (generating Cucumber report before test method run ends).
Below is my code:
Test.class
public class AllTestsRunnerTest {
#Test
void testAll() {
Results results = Karate.run().relativeTo(getClass()).tags("~#ignore").outputCucumberJson(true).parallel(1);
generateReport(results.getReportDir());
assertEquals(0, results.getFailCount(), "Expected failures");
}
public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true);
List<String> jsonPaths = new ArrayList<>(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "Your project name here");
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
}
pom.xml
<dependencies>
<!-- Functional / UI / API -->
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-junit5</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
<!-- Reporting -->
<dependency>
<groupId>net.masterthought</groupId>
<artifactId>cucumber-reporting</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Note: In my feature files I do not have the def report and def result3 directives set.
Hope this helps!
This question already has answers here:
How to export swagger.json (or yaml)
(7 answers)
Closed 3 years ago.
I am using java spring boot framework to create REST api for my project and I am using "springfox-swagger2 and springfox-swagger-ui" for generating swagger documentation. I am able to see my documentation using the URL http://localhost:8080/swagger-ui.html.
How can I create or generate swagger.json / spec.json, The documentation should not be with this application, we are using a separate application for listing the API docs.
You can get the url with your swagger-ui html page:
GET http://localhost:8080/v2/api-docs?group=App
And actually you can get all the urls with chrome/firefox develop tools network feature.
If you use Maven, you can generate client and server side documentation (yaml, json and html) by using swagger-maven-plugin
Add this to your pom.xml:
.....
<plugin>
<groupId>com.github.kongchen</groupId>
<artifactId>swagger-maven-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<apiSources>
<apiSource>
<springmvc>true</springmvc>
<locations>com.yourcontrollers.package.v1</locations>
<schemes>http,https</schemes>
<host>localhost:8080</host>
<basePath>/api-doc</basePath>
<info>
<title>Your API name</title>
<version>v1</version>
<description> description of your API</description>
<termsOfService>
http://www.yourterms.com
</termsOfService>
<contact>
<email>your-email#email.com</email>
<name>Your Name</name>
<url>http://www.contact-url.com</url>
</contact>
<license>
<url>http://www.licence-url.com</url>
<name>Commercial</name>
</license>
</info>
<!-- Support classpath or file absolute path here.
1) classpath e.g: "classpath:/markdown.hbs", "classpath:/templates/hello.html"
2) file e.g: "${basedir}/src/main/resources/markdown.hbs",
"${basedir}/src/main/resources/template/hello.html" -->
<templatePath>${basedir}/templates/strapdown.html.hbs</templatePath>
<outputPath>${basedir}/generated/document.html</outputPath>
<swaggerDirectory>generated/swagger-ui</swaggerDirectory>
<securityDefinitions>
<securityDefinition>
<name>basicAuth</name>
<type>basic</type>
</securityDefinition>
</securityDefinitions>
</apiSource>
</apiSources>
</configuration>
</plugin>
........
You can download *.hbs template at this address:
https://github.com/kongchen/swagger-maven-example
Execute mvn swagger:generate
JSon documentation will be generated at your project /generated/swagger/ directory.
Past it on this address :
http://editor.swagger.io
And generate what ever you want ( Server side or Client side API in your preferred technology )
I'm a little late here, but I just figured out that you can open your browser console and find the URL to the GET request that returns the JSON definition for your Swagger docs. The following technique worked for me when mapping my API to AWS API Gateway.
To do this:
Navigate to your Swagger docs endpoint
Open the browser console
Refresh the page
Navigate to the network tab and filter by XHR requests
Right click on the XHR request that ends in ?format=openapi
You can now just copy and paste that into a new JSON file!
I have done this with a small trick
I have added the following code in the end of my home controller test case
import org.springframework.boot.test.web.client.TestRestTemplate;
public class HomeControllerTest extends .... ...... {
#Autowired
private TestRestTemplate restTemplate;
#Test
public void testHome() throws Exception {
//.......
//... my home controller test code
//.....
String swagger = this.restTemplate.getForObject("/v2/api-docs", String.class);
this.writeFile("spec.json", swagger );
}
public void writeFile(String fileName, String content) {
File theDir = new File("swagger");
if (!theDir.exists()) {
try{
theDir.mkdir();
}
catch(SecurityException se){ }
}
BufferedWriter bw = null;
FileWriter fw = null;
try {
fw = new FileWriter("swagger/"+fileName);
bw = new BufferedWriter(fw);
bw.write(content);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null)
bw.close();
if (fw != null)
fw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
I don't know this is right way or not But it is working :)
Dependency
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
You should be able to get your swagger.json at
http://localhost:8080/api-docs
assuming your don't have kept the versioning as in the pet store sample application. In that case the URL would be:
http://localhost:8080/v2/api-docs
To get the api json definition for REST API, if swagger is configured properly. you can use directly swagger/docs/v1, this means the complete url will be, if version v1 (or just specify the version)
http://localhost:8080/swagger/docs/v1
I have some jar file (custom) which I need to publish to Sonatype Nexus repository from Groovy script.
I have jar located in some path on machine where Groovy script works (for instance: c:\temp\module.jar).
My Nexus repo url is http://:/nexus/content/repositories/
On this repo I have folder structure like: folder1->folder2->folder3
During publishing my jar I need to create in folder3:
New directory with module's revision (my Groovy script knows this revision)
Upload jar to this directory
Create pom, md5 and sha1 files for jar uploaded
After several days of investigation I still have no idea how to create such script but this way looks very clear instead of using direct uploading.
I found http://groovy.codehaus.org/Using+Ant+Libraries+with+AntBuilder and some other stuff (stackoverflow non script solution).
I got how to create ivy.xml in my Groovy script, but I don't understand how to create build.xml and ivysetting.xml on the fly and setup whole system to work.
Could you please help to understand Groovy's way?
UPDATE:
I found that the following command works fine for me:
curl -v -F r=thirdparty -F hasPom=false -F e=jar -F g=<my_groupId> -F a=<my_artifactId> -F v=<my_artifactVersion> -F p=jar -F file=#module.jar -u admin:admin123 http://<my_nexusServer>:8081/nexus/service/local/repositories
As I understand curl perform POST request to Nexus services. Am I correct?
And now I'm trying to build HTTP POST request using Groovy HTTPBuilder.
How I should transform curl command parameters into Groovy's HTTPBuilder request?
Found a way to do this with the groovy HttpBuilder.
based on info from sonatype, and a few other sources.
This works with http-builder version 0.7.2 (not with earlier versions)
And also needs an extra dependency: 'org.apache.httpcomponents:httpmime:4.2.1'
The example also uses basic auth against nexus.
import groovyx.net.http.Method
import groovyx.net.http.ContentType;
import org.apache.http.HttpRequest
import org.apache.http.HttpRequestInterceptor
import org.apache.http.entity.mime.MultipartEntity
import org.apache.http.entity.mime.content.FileBody
import org.apache.http.entity.mime.content.StringBody
import org.apache.http.protocol.HttpContext
import groovyx.net.http.HttpResponseException;
class NexusUpload {
def uploadArtifact(Map artifact, File fileToUpload, String user, String password) {
def path = "/service/local/artifact/maven/content"
HTTPBuilder http = new HTTPBuilder("http://my-nexus.org/")
String basicAuthString = "Basic " + "$user:$password".bytes.encodeBase64().toString()
http.client.addRequestInterceptor(new HttpRequestInterceptor() {
void process(HttpRequest httpRequest, HttpContext httpContext) {
httpRequest.addHeader('Authorization', basicAuthString)
}
})
try {
http.request(Method.POST, ContentType.ANY) { req ->
uri.path = path
MultipartEntity entity = new MultipartEntity()
entity.addPart("hasPom", new StringBody("false"))
entity.addPart("file", new FileBody(fileToUpload))
entity.addPart("a", new StringBody("my-artifact-id"))
entity.addPart("g", new StringBody("my-group-id"))
entity.addPart("r", new StringBody("my-repository"))
entity.addPart("v", new StringBody("my-version"))
req.entity = entity
response.success = { resp, reader ->
if(resp.status == 201) {
println "success!"
}
}
}
} catch (HttpResponseException e) {
e.printStackTrace()
}
}
}
`
Ivy is an open source library, so, one approach would be to call the classes directly. The problem with that approach is that there are few examples on how to invoke ivy programmatically.
Since groovy has excellent support for generating XML, I favour the slightly dumber approach of creating the files I understand as an ivy user.
The following example is designed to publish files into Nexus generating both the ivy and ivysettings files:
import groovy.xml.NamespaceBuilder
import groovy.xml.MarkupBuilder
// Methods
// =======
def generateIvyFile(String fileName) {
def file = new File(fileName)
file.withWriter { writer ->
xml = new MarkupBuilder(writer)
xml."ivy-module"(version:"2.0") {
info(organisation:"org.dummy", module:"dummy")
publications() {
artifact(name:"dummy", type:"pom")
artifact(name:"dummy", type:"jar")
}
}
}
return file
}
def generateSettingsFile(String fileName) {
def file = new File(fileName)
file.withWriter { writer ->
xml = new MarkupBuilder(writer)
xml.ivysettings() {
settings(defaultResolver:"central")
credentials(host:"myrepo.com" ,realm:"Sonatype Nexus Repository Manager", username:"deployment", passwd:"deployment123")
resolvers() {
ibiblio(name:"central", m2compatible:true)
ibiblio(name:"myrepo", root:"http://myrepo.com/nexus", m2compatible:true)
}
}
}
return file
}
// Main program
// ============
def ant = new AntBuilder()
def ivy = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.ivy.ant')
generateSettingsFile("ivysettings.xml").deleteOnExit()
generateIvyFile("ivy.xml").deleteOnExit()
ivy.resolve()
ivy.publish(resolver:"myrepo", pubrevision:"1.0", publishivy:false) {
artifacts(pattern:"build/poms/[artifact].[ext]")
artifacts(pattern:"build/jars/[artifact].[ext]")
}
Notes:
More complex? Perhaps... however, if you're not generating the ivy file (using it to manage your dependencies) you can easily call the makepom task to generate the Maven POM files prior to upload into Nexus.
The REST APIs for Nexus work fine. I find them a little cryptic and of course a solution that uses them cannot support more than one repository manager (Nexus is not the only repository manager technology available).
The "deleteOnExit" File method call ensures the working files are cleaned up properly.
Can anyone provide an updated application skeleton for a Red5 application? From what I have found the logging system changed from Log4j. I've been looking for some tutorials just to setup everything but can't really find something that simply works.
In addiction, can anyone provide a simple tutorial with a server application and Flex client?
Thanks in advance!
I struggled a lot with that.. This reference worked for me:
http://fossies.org/unix/privat/red5-1.0.0-RC2.tar.gz:a/red5-1.0.0/doc/reference/html/logging-setup.html
The trick was to Remove any log4j.properties or log4j.xml files and Remove any "log4j" listeners from the web.xml
Create a logback-myApp.xml where myApp is the name for your webapp and place it on your webapp classpath (WEB-INF/classes or in your application jar within WEB-INF/lib)
and im my app i did:
import org.slf4j.Logger;
import org.red5.logging.Red5LoggerFactory;
and then:
private static Logger log = Red5LoggerFactory.getLogger(MyClassName.class, "myApp");
the clients actionscript looks like this:
// Initializiing Connection
private function initConnection():void{
nc = new NetConnection();
nc.client = new NetConnectionClient();
nc.objectEncoding = flash.net.ObjectEncoding.AMF0;
nc.connect(rtmpPath.text,true); //Path to FMS Server e.g. rtmp://<hostname>/<application name>
nc.addEventListener("netStatus", publishStream); //Listener to see if connection is successful
}
private function publishStream(event:NetStatusEvent):void{
if(nc.connected){
nsPublish = new NetStream(nc); //Initializing NetStream
nsPublish.attachCamera(Camera.getCamera());
nsPublish.attachAudio(Microphone.getMicrophone()); //Attaching Camera & Microphone
nsPublish.publish(streamName.text,'live'); //Publish stream
mx.controls.Alert.show("Published");
}
else{
mx.controls.Alert.show("Connection Error");
}
}
How to save a string into file (file.superlongextention) in applicationdirectory and get its real locationon Hard drive (like C:/files/...)?
For security reason you can't write into the Application directory (for testing you can but it 's realy not recommended).
You can write into the Application Storage directory to store your application data.
Use File then FileStream to write your data.
To get the path of the file use nativePath.
import flash.filesystem.File;
import flash.filesystem.FileStream;
import flash.filesystem.FileMode;
import mx.controls.Alert;
// get a file reference to the storage directory
var file:File=File.applicationStorageDirectory.resolvePath("myfile.withextension");
// create a file stream
var fs:FileStream=new FileStream();
// open the stream for writting
fs.open(file, FileMode.WRITE);
// write the string data down to the file
fs.writeUTFBytes("my string to save");
// ok close the file stream
fs.close();
// show the path to the file we have saved using Alert
Alert.show(file.nativePath);
but you can save file in Applicationdirectory
var appPath:File = File.applicationDirectory.resolvePath("");
var fromUserPath:File = File.userDirectory.resolvePath(appPath.nativePath);
Thanks to Tanel Teemusk
http://blog.teemusk.com/2011/10/writing-to-applicationdirectory-with-adobe-air/