Extensis Logo SUPPORT | FORUMS | KNOWLEDGE BASE

Upload an asset VIA the API


#1

Hi,

I am currently trying to upload assets via the Java or HTTP API. I can see that this is now down by using the File Transfer Servlet. Anything I POST to this I get a 400 response and nothing in the logs.
I have used the Java API example given here http://doc.extensis.com/api/portfolio-server/HTTPuploadFile.html
I am aware this is probably old documentation. I am trying to avoid uploading a file via ftp and then using the API to upload it via the filesystem.

Can this be done in portfolio 2017?

Thank you in advance,
Michael.


#2

Yes, absolutely, this can be done in Portfolio 2017. There is also another endpoint that can be used as well, but I believe the documentation although old is still correct. Can you get me the source code you are using?


#3

I verified that the sample code in the link you sent can be used (with some obvious modifications) to upload a file with a recent version of Portfolio. The modifications were to define a sessionId, catalogId, the server address and port, valid paths to a local file and destination (colon-delimited) path. Please get me your code and I may be able to spot the problem.


#4

Hi,

The code I am using is as follows:

private static void uploadFile(String sessionId, String catalogueId,String imageName, String ip, String port) throws Exception {
 // Where the file will be saved on the server.
    String destination = ":";
    File imagePath = new File(imageName);
    // The name of the file.
    String item = imagePath.getName();
    if (imagePath.exists()) {
        String cr = "\r\n";
        String boundary = "----" + UUID.randomUUID().toString().replace("-", "");
        String bar = "--" + boundary + cr;
        String sHeader = bar;
        sHeader += "Content-Disposition: form-data; name=\"sessionId\"" + cr + cr + sessionId + cr;
        sHeader += bar;
        sHeader += "Content-Disposition: form-data; name=\"catalogId\"" + cr + cr + catalogueId + cr;
        sHeader += bar;
        sHeader += "Content-Disposition: form-data; name=\"destinationFolder\"" + cr + cr + destination + cr;
        sHeader += bar;
        sHeader += "Content-Disposition: form-data; name=\"filename\"" + cr + cr + item + cr;
        sHeader += bar;
        sHeader += "Content-Disposition: form-data; name=\"action\"" + cr + cr + "upload" + cr;
        sHeader += bar;
        sHeader += "Content-Disposition: form-data; name=\"Filedata\"; filename=\"" + item + "\"" + cr;
        sHeader += "Content-Type: application/octet-stream" + cr + cr;
 // Convert the String to a Byte array.
        byte[] header = sHeader.getBytes("UTF-8");
        String footerStr = cr + "--" + boundary + "--";
        byte[] footer = footerStr.getBytes("UTF-8");
 //Set up the connection URL.
        try {
            URL url = new URL("http://" + ip + ":" + port + "/FileTransfer/upload");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "close");
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
            conn.setRequestProperty("Accept-Types", "text/*");
            conn.setChunkedStreamingMode(2048);
            conn.setRequestProperty("Content-Length", String.valueOf(footer.length + header.length + (int) imagePath.length()));
            OutputStream os = conn.getOutputStream();
 // Upload the Header
            os.write(header, 0, header.length);
 // Read the image file into a Byte array
            byte[] buf = new byte[8192 * 16];
            FileInputStream imageFile = new FileInputStream(imagePath);
            while (true) {
                int nread = imageFile.read(buf);
                if (nread <= 0)
                    break;
  // Write the Byte array to the Portfolio server
                os.write(buf, 0, nread);
            }
  // Once the image has been written.  Write the footer byte array.
            os.write(footer, 0, footer.length);
            os.flush();
            BufferedReader in = new BufferedReader( new InputStreamReader( conn.getInputStream()));
            String textResult = "";
            String line = null;
            while ((line = in.readLine()) != null) {
                textResult += line;
            }
  // Print the resulting Record ID.
            System.out.println(textResult.trim());
            os.close();
        } catch (MalformedURLException e) {
            System.out.println("Failed: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("Failed: " + e.getMessage());
        }
    } else {
        System.out.println("File doesn't exist.");
    }
}

Please note that I have tried several different destinations and several different images all give a 400 back

Thank you in advance,
Michael.


#5

Hi Michael,

I ran your code. When I first ran it, I got a 500 error which was because the destination didn’t exist. (That is a bug - we should be returning a 404 and a message explaining the problem.) However, when I changed the destination from “:” to something that exists on my test server ("::administorsmbp2:Shared:Portfolio:fs Files" in my case), the asset was added successfully. I also tested with a vault catalog with the destination folder set to “:”.

So unfortunately, I was not able to reproduce what you are seeing. It’s unfortunate that the error message is not more helpful. Are you able to configure the Portfolio server for debug logging? Have you looked in the server.log file? Is there any sign of an Exception thrown?

-Brooks


#6

Hi Brooks,

I am still trying to figure this out.
I have checked the logs and cannot see any errors.

However, I did run it on another implementation and gave a false catalog id (because I didn’t want to write an image to this implementation) and got a 500 which seems correct.
This is making me think that I am missing a license or I have a misconfiguration. I have reinstalled portfolio (latest version) and I still get a 400.

I do not have netpublish. Is this needed?

Thanks,
Michael.


#7

I’m looking in the code to see where we send back a 400 (bad request). There are a few places, but only one seems likely. If you send an empty sessionId you will get a 400. (If it’s non-empty and invalid or null, you will get a 500.)

The other places are:

  • If the request is not multipart/form-data (this seems impossible with the code you are using)
  • If there is no filename (seems unlikely, but you should double check)

Please add these lines to the top of uploadFile(), compile and run your code and send me the output.
System.out.println(“sessionId=” + sessionId);
System.out.println(“catalogueId=” + catalogueId);
System.out.println(“imageName=” + imageName);
System.out.println(“ip=” + ip);
System.out.println(“port=” + port);


#8

HI Again,

The output is:
sessionId=B9F4D6AD-3B11-EAA2-8C48-3EFB17302640
catalogueId=5322A05A-DEE2-DB98-3020-114B017B1D5F
imageName=/home/michael/image001.jpg
ip=192.168.1.128
port=8090
item=image001.jpg
Failed: Server returned HTTP response code: 400 for URL: http://192.168.1.128:8090/FileTransfer/upload

I added an extra system out to get the file name

Thank you for looking at this.
Michael.


#9

Unfortunately, that didn’t give me any more insight into this. Can you please do the following:

  1. Tell me the version of the Portfolio Server you are using and the OS it is running on.
  2. Switch the Portfolio Server to debug level logging (admin–>Global Settings–>Logging Configuration)
  3. Show me the applicable log output from server.log. (After you have run the upload, you may want to switch the logging back to what it was.)
  4. Tell me what client OS you are using.

If the debug logging doesn’t tell us something I can try making a build with extra logging in it that is compatible with the version of Portfolio you are using.

Regards,
Brooks


#10

Hi Brooks,

  1. Windows Server 2012 R2
    2/3.

    2017-11-29 11:55:34,791 DEBUG [extensis.portfolio.server.service.AssetSEI] (http-executor-threads - 36)   AssetSEI.getRSAPublicEncryptionKey invoked.
    2017-11-29 11:55:34,976 DEBUG [extensis.portfolio.server.service.AssetSEI] (http-executor-threads - 37) AssetSEI.login invoked.
    2017-11-29 11:55:34,998 DEBUG [extensis.portfolio.server.implementation.Login] (http-executor-threads - 37) [login] params={userName=K-Int, password=******}.
    2017-11-29 11:55:34,999 DEBUG [extensis.esp.db.query.hard.HardQueryBuilder] (http-executor-threads - 37) 
    SELECT {rootEntity.*}
    FROM dam__dam_user rootEntity
    WHERE lower(esp_user_shortname)=:attr0Val
    
     :attr0Val='K-Int'
    

However this output does not seem like what I would be expecting.

  1. the client OS is Linux.

Thank you,
Michael.


#11

Hi Michael,

Knowing the OS’s involved is helpful, but I also need to know what version of Portfolio server you are using. Please reproduce the problem and send me the most recent server.log file as well as the latest usage.log file.

Regards,
Brooks


#12

This is very frustrating. We may want to enlist the help of Extensis tech support in troubleshooting this. They can help get me log files and set up a remote connection to the server machine if needed. However, in the meantime please send me the information requested above. Thanks for your patience.


#13

Also, are you able to upload using the Portfolio client?


#14

Hi Brooks,

I have found the issue.
When portfolio was first set up some fields were set to required.
Because I wasn’t providing these fields then I got a 400 response.

I removed the required fields and it now works.

Thank you for your help regarding this.

Michael.


#15

Glad you found the problem! Funny, I thought I tested that, but that I got a different error. Maybe different version of Portfolio server?