How to use environment variable values to access cloudinary API in java? - java

I have a requirement of uploading images to cloudinary using cloudinary's java API.I have created cloudinary account through which i got api Cloud name,API Key,API Secret. Using these things i am able to upload my images to cloudinary like bellow:
#PostMapping("/uploadPic")
public ResponseEntity<Object> upload(#RequestParam("file") MultipartFile multipartFile){
String cloudinaryImgURL=null;
try {
File fileDir = new File("rowFiles");
if (! fileDir.exists()){
fileDir.mkdir();
}
String fileName=multipartFile.getOriginalFilename();
File physicalFile=new File(multipartFile.getOriginalFilename());
FileOutputStream fout=new FileOutputStream(fileDir.getName()+"/"+physicalFile);
fout.write(multipartFile.getBytes());
fout.close();
//For stack-overflow question using dummy values for credientials.
Cloudinary cloudinary = new Cloudinary(ObjectUtils.asMap(
"cloud_name", "your_cloud_name",
"api_key", "your_api_key",
"api_secret", "your_secret_key"));
File toUpload = new File("rowFiles/"+fileName);
Map params = ObjectUtils.asMap("public_id", "SRWRestImageBase/"+fileName);
Map uploadResult =Singleton.getCloudinary().uploader().upload(toUpload, params);
toUpload.delete();
System.out.println("==============>>"+uploadResult.get("url"));
cloudinaryImgURL=uploadResult.get("url").toString();
} catch (Exception e) {
System.out.println("upload:"+e.getMessage());
// TODO: handle exception
}
return new ResponseEntity<Object>("File uploaded successfully:"+cloudinaryImgURL,HttpStatus.OK);
}
But now my problem is that i keep this code in public git repo, and from there i push this code to Heroku. But using this method will expose my cloudinary details like Cloud name,API Key,API Secret to everyone which i don't want.
Looking at cloudinary's documentation for getting started i found the way of using environment variable to store these values and access it from there, but document doesn't guide me properly.
I have used
In a Java EE environment you can set an environment variable available to your Java EE container:
CLOUDINARY_URL=cloudinary://{api_key}:{api_secret}#{cloud_name}
This will enable you to receive a Cloudinary instance:
Cloudinary cloudinary = Singleton.getCloudinary();
But i am getting compile-time error for class Singleton that it is not able to find in any jar. Looking at some other article, this class should com.cloudinary.Singleton, but my cloudinary jar does not have this class.
I am using cloudinary gradle dependancy as:
// https://mvnrepository.com/artifact/com.cloudinary/cloudinary-http43
compile group: 'com.cloudinary', name: 'cloudinary-http43', version: '1.2.2'
It would be appreciated if someone can guide me in right direction.
Thanks in Advance.

I have found my own solution.
We have to set environment variable CLOUDINARY_URL=cloudinary://{api_key}:{api_secret}#{cloud_name} and restart eclipse to reflect the environment variable changes and following changes. This way it wont expose my account details to public repo.
#PostMapping("/uploadPic")
public ResponseEntity<Object> upload(#RequestParam("file") MultipartFile multipartFile){
String cloudinaryImgURL=null;
try {
File fileDir = new File("rowFiles");
if (! fileDir.exists()){
fileDir.mkdir();
}
String fileName=multipartFile.getOriginalFilename();
File physicalFile=new File(multipartFile.getOriginalFilename());
FileOutputStream fout=new FileOutputStream(fileDir.getName()+"/"+physicalFile);
fout.write(multipartFile.getBytes());
fout.close();
File toUpload = new File("rowFiles/"+fileName);
Cloudinary cloudinary = new Cloudinary();
System.out.println("API Key:"+cloudinary.config.apiKey);
Map params = ObjectUtils.asMap("public_id", "SRWRestImageBase/"+fileName);
Map uploadResult = cloudinary.uploader().upload(toUpload, params);
toUpload.delete();
System.out.println("==============>>"+uploadResult.get("url"));
cloudinaryImgURL=uploadResult.get("url").toString();
} catch (Exception e) {
System.out.println("upload:"+e.getMessage());
}
return new ResponseEntity<Object>("File uploaded successfully:"+cloudinaryImgURL,HttpStatus.OK);
}

Related

Vaadin Upload UnsupportedOperationException issue while creating a File

I'm trying to get a midi file through a form in Vaadin, but when I try to get this File into a File class and getting a UnsupportedOperationException. This is happening in the File midiFile = fileData.getFile();
java.lang.UnsupportedOperationException: class java.io.ByteArrayOutputStream not supported. Use a UploadOutputStream
In the form it seems that the file has been loaded, but there was an error as trying to generate the File. I don't know why is this happening as I follow the methods in Vaadin documentation to get the file from the Upload. And I don't understand why it says in this exception "Happens if outputBuffer is not an UploadOutputStream".
https://vaadin.com/api/platform/23.0.9/com/vaadin/flow/component/upload/receivers/FileData.html
And if I run getFileName() from FileData after getting it from the MemoryBuffer I see that the recently uploaded file is there.
https://vaadin.com/api/platform/23.0.9/com/vaadin/flow/component/upload/receivers/MemoryBuffer.html
This is the full code.
import com.vaadin.flow.component.upload.Upload;
import com.vaadin.flow.component.upload.receivers.FileData;
import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
public MainView() {
MemoryBuffer memoryBuffer = new MemoryBuffer();
Upload midiFileUpload = new Upload(memoryBuffer);
midiFileUpload.setDropLabel(new Label("Upload a file in .mid format"));
midiFileUpload.addSucceededListener(event -> {
InputStream inputFileData = memoryBuffer.getInputStream();
String fileName = event.getFileName();
long contentLength = event.getContentLength();
String mimeType = event.getMIMEType();
FileData fileData = memoryBuffer.getFileData();
try {
File midiFile = fileData.getFile();
} catch (UnsupportedOperationException uoe) {
System.out.println("OutputBuffer is not an UploadOutputStream.");
uoe.printStackTrace();
} catch (NullPointerException npe) {
System.out.println("Empty buffer.");
npe.printStackTrace();
}
});
}
As the name implies, MemoryBuffer stores the uploaded file in memory, so it can't provide a java.io.File, only an InputStream to read the data from. If you want Upload to use a (temporary!) file, use a FileBuffer instead.
I don't know why this issue is happening but I solved it just changing from MemoryBuffer to FileBuffer class. Now it works.

Upload file to Spring Boot Resource Folder, should not be that hard right

I checked all over the internet and still cannot find the correct answer. I want to upload a file to the resources folder from Spring. So I can get the file from the heroku server when I deploy it.
For example applicationname/herokuapp.com/image.jpg
The structure of my app:
I tried and got a few problems :
File not found exception
Illegal char <:> at index 2
The file path I get is in the target folder??
Can't find path
I just need to get the correct path to the resources folder but I can't get it.
My controller with the following method looks like this:
#PostMapping(value = "/sheetmusic")
public SheetMusic create(HttpServletRequest request, #RequestParam("file") MultipartFile file, #RequestParam("title") String title, #RequestParam("componist") String componist, #RequestParam("key") String key, #RequestParam("instrument") String instrument) throws IOException {
URL s = ResourceUtils.getURL("classpath:static/");
String path = s.getPath();
fileService.uploadFile(file,path);
SheetMusic sheetMusic = new SheetMusic(title,componist,key,instrument,file.getOriginalFilename());
return sheetMusicRepository.save(sheetMusic);
}
The FileService:
public void uploadFile(MultipartFile file, String uploadDir) {
try {
Path copyLocation = Paths
.get(uploadDir + File.separator + StringUtils.cleanPath(file.getOriginalFilename()));
Files.copy(file.getInputStream(), copyLocation, StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
}
}
I read something about jar but I don't understand it. I did not think it was this hard to just upload a file to a folder but I hope you guys can help me out!
EDIT :
When I add this :
String filePath = ResourceUtils.getFile("classpath:static").toString();
It will upload to the target folder which is not right.
EDIT 2 : IT IS FIXED
This is the right way to get the correct path :
String path = new File(".").getCanonicalPath() + "/src/main/webapp/WEB-INF/images/";
fileService.uploadFile(file,path);
My folder structure is the following:
main
-java
- webapp
- WEB-INF
- images
Then I had to put this code into my MainApplicationClass
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// Register resource handler for images
// Register resource handler for images
registry.addResourceHandler("/images/**").addResourceLocations("/WEB-INF/images/")
.setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic());
}
What you are trying to do here (replacing a file/uploading a file INTO a package .jar file) does not work, it is literally impossible.
You need to upload your file somewhere else, be that S3, some network drive etc, so that you application can reference it.

Unable to attach file to issue in jira via rest api Java

I want to attach multiple files to issue. I'm able to create issue successfully however i am facing problem in attaching documents after creating issue. I have referred to this link SOLVED: attach a file using REST from scriptrunner
I am getting 404 error even though issue exists and also user has all the permissions.
File fileToUpload = new File("D:\\dummy.txt");
InputStream in = null;
try {
in = new FileInputStream(fileToUpload);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
HttpResponse < String > response3 = Unirest
.post("https://.../rest/api/2/issue/test-85/attachments")
.basicAuth(username, password).field("file", in , "dummy.txt")
.asString();
System.out.println(response3.getStatus());
here test-85 is a issueKey value.
And i am using open-unirest-java-3.3.06.jar. Is the way i am attaching documents is correct?
I am not sure how open-unirest manages its fields, maybe it tries to put them as json field, rather than post content.
I've been using Rcarz's Jira client. It's a little bit outdated but it still works.
Maybe looking at its code will help you, or you can just use it directly.
The Issue class:
public JSON addAttachment(File file) throws JiraException {
try {
return restclient.post(getRestUri(key) + "/attachments", file);
} catch (Exception ex) {
throw new JiraException("Failed add attachment to issue " + key, ex);
}
}
And in RestClient class:
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
public JSON post(String path, File file) throws RestException, IOException, URISyntaxException {
return request(new HttpPost(buildURI(path)), file);
}
private JSON request(HttpEntityEnclosingRequestBase req, File file) throws RestException, IOException {
if (file != null) {
File fileUpload = file;
req.setHeader("X-Atlassian-Token", "nocheck");
MultipartEntity ent = new MultipartEntity();
ent.addPart("file", new FileBody(fileUpload));
req.setEntity(ent);
}
return request(req);
}
So I'm not sure why you're getting a 404, Jira is sometime fuzzy and not really clear about its error, try printing the full error, or checking Jira's log if you can. Maybe it's just the "X-Atlassian-Token", "nocheck", try adding it.

Can not read file when run within jar file

I have an akka http service. I simply return the api documentation for a get request. The documentation is in html file.
It all works fine when run within the IDE. When I package it as a jar I get error 'resource not found'. I am not sure why it can not read the html file when hosted in a jar and works fine when in IDE.
Here is the code for the route.
private Route topLevelRoute() {
return pathEndOrSingleSlash(() -> getFromResource("asciidoc/html/api.html"));
}
The files are located in resource path.
I have got this working now.
I am doing this.
private Route topLevelRoute() {
try {
InputStreamReader inputStreamReader = new InputStreamReader(getClass().getResourceAsStream("/asciidoc/html/api.html"));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
//Get the stream input into string builder
reader.lines().forEach(s -> strBuild.append(s));
inputStreamReader.close();
bufferedReader.close();
//pass the string builder as string with contenttype set to html
complete(HttpEntities.create(ContentTypes.TEXT_HTML_UTF8, strBuild.toString()))
} catch (Exception ex) {
//Catch any exception here
}
}

How to download files stored in monogdb with gridfs using spring mvs

I have saved a file into mongoDB using gridFS like so.
Mongo mongo = new Mongo("XXXXX", XXXX);
DB db = mongo.getDB("XXX");
GridFS fs = new GridFS(XXX);
File install = new File("C:\\Users\\Nabeel\\Desktop\\docs.txt");
GridFSInputFile inFile = fs.createFile(install);
inFile.save();
Now I want download that file using spring MVC. I don't seep to able to find example on how i can get the file back as gridFS has converted the file into binary.
An example code would be nice as i am new to all this.
Thanks you in advance
You can do something like this for serving file :
public void downloadFile(String videoId , HttpServletResponse response ) {
InputStream is = null;
ApplicationContext ctx = new AnnotationConfigApplicationContext(MongoDBConfiguration.class);
GridFsOperations gridOperations = (GridFsOperations) ctx.getBean("YourBeanName");
List<GridFSDBFile> result = gridOperations.find(new Query().addCriteria(Criteria.where("_id").is(videoId)));
for (GridFSDBFile file : result) {
try {
/* send file */
} catch (Exception e) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
}
}
Send file example here: How do I return a video with Spring MVC so that it can be navigated using the html5 <video> tag?
This link about video serving but it can give you an idea. Use method 2 in the link and GridFSDBFile's getInputStream() method.

Categories

Resources