cancel
Showing results for 
Search instead for 
Did you mean: 

CMIS REST upload problem with non octet-stream content

iblanco
Confirmed Champ
Confirmed Champ
I've developed ( copy pasted from different examples ) a little proof of concept that uploads a file to an Alfresco repository using CMIS's REST API.

It works for content that has type "application/octet-stream" (which is the default content type), but for other content types the file is created in alfresco but its content is empty. If I always set the content type as "application/octet-stream" all the files upload right, but obviously their content type is not correctly set, and of course rules and behavoiurs related to the content type are not triggered.

I haven't found this bug in Jira but I wanted to check here before reporting it as a bug, I might be doing something wrong.

Here you have the code in case you are interested in ( I use mime-utils to obtain the mime type 😞


package es.binovo.cmis;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collection;

import eu.medsea.mimeutil.MimeType;
import eu.medsea.mimeutil.MimeUtil;

import sun.misc.BASE64Encoder;

public class ProofOfConcept {

   /**
    * @param args
    */
   public static void main(String[] args) {
      ProofOfConcept poc;

      if (args.length != 4) {
         System.err.println("Error: número de parámetros inadecuado.");
         System.out
               .println("Modo de uso: ProofOfConcept <usuario> <contraseña> http://<cmis_server>:<port>/<cmis-api>/<folder-url>/<children> <fichero_a_subir>");
         System.out
               .println("Ejemplo: java es.binovo.cmis.ProofOfConcept admin admin http://pruebas.binovo:8180/alfresco/service/api/path/workspace/SpacesStore/Company%20Home/children /usr/share/pixmaps/gnome-term-tiger.png");
         return;
      }

      try {
         poc = new ProofOfConcept(args[0], args[1], new URL(args[2]),
               new File(args[3]));
         poc.createContent();
      } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }

   private URL url;

   private File file;

   private static final String mensaje = "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:cmis=\"http://www.cmis.org/2008/05\">\n"
         + "\t<title>FILE_NAME</title>\n"
         + "\t<content type=\"MIME_TYPE\">CONTENT</content>\n"
         + "\t<cmis:object>\n"
         + "\t\t<cmis:properties>\n"
         + "\t\t\t<cmis:propertyString cmis:name=\"ObjectTypeId\"><cmis:value>document</cmis:value></cmis:propertyString>\n"
         + "\t\t</cmis:properties>\n" + "\t</cmis:object>\n" + "</entry>\n";
   private String usuario;

   private String password;

   public ProofOfConcept(String usuario, String password, URL url, File file) {
      super();
      this.usuario = usuario;
      this.password = password;
      this.url = url;
      this.file = file;
   }

   @SuppressWarnings("unchecked")
   private void createContent() throws IOException {
      BASE64Encoder encoder = new BASE64Encoder();
      FileInputStream fis = new FileInputStream(file);
      DataInputStream dis = new DataInputStream(fis);
      // Create the byte array to hold the data
      byte[] bytes = new byte[(int) file.length()];
      dis.readFully(bytes);

      Collection<MimeType> mimeTypes = MimeUtil.getMimeTypes(file);
      MimeType mimeType = MimeUtil.getMostSpecificMimeType(mimeTypes);
      if(mimeType == null) mimeType = MimeUtil.UNKNOWN_MIME_TYPE;
      
      System.out.println("Content mime type is: " + mimeType.toString());
      
      String datos = ProofOfConcept.mensaje;
      datos = datos.replaceFirst("FILE_NAME", file.getName());
      datos = datos.replaceFirst("MIME_TYPE", mimeType.toString());
      datos = datos.replaceFirst("CONTENT", encoder.encode(bytes));
      String auth = encoder.encode((usuario + ":" + password).getBytes());

      URLConnection conn = url.openConnection();
      conn.setDoOutput(true);
      conn.setRequestProperty("Authorization", "Basic " + auth);
      conn.setRequestProperty("Content-Type",
            "application/atom+xml;type=entry");
      OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
      out.write(datos);
      out.close();

      // A ver que nos cuentan.
      String decodedString;

      BufferedReader in = new BufferedReader(new InputStreamReader(conn
            .getInputStream()));

      while ((decodedString = in.readLine()) != null) {
         System.out.println(decodedString);
      }
      in.close();

   }

}



UPDATE: It seems that it also works for image/png content type, but not for application/xml or or text/xml , it seems like something related to text formats.
3 REPLIES 3

syberyan
Champ in-the-making
Champ in-the-making
Alfresco doesn't expect XML content to be base64 encoded. It should be plain text.
I had the same problem a while ago 😉

Cheers,
Chris

iblanco
Confirmed Champ
Confirmed Champ
Hy syberyan,

Thanks for your answer. I've checked not encoding the content when it is of XML type but not luck.

I have tried 3 different ways:

1.- Just put the content "as is", and I get a 500 Server error.

That is normal due to the fact that the CMIS API tries to "interpret" my XML which is not valid atom.

2.- Adding a CDATA enclosuer.

It does not give an error but the uploaded content node is empty.

3.- Scaping the XML with Apache's "common-langs" libraries escapeXml function.

It does not give an error but the uploaded content node is empty.


After all, even if Alfresco does not expect XML content to be BASE64 encoded it should at least put the content into the node, even if it was without decoding. Is there any special property I should add to the CMIS request entry so that I can upload plain text files and xmls ?

Thanks.

syberyan
Champ in-the-making
Champ in-the-making
I dumped my atom entry going over the wire, maybe this can help you:
(This is created with an abdera client)
(Using alfresco 3.2 preview 2)

<entry xmlns="http://www.w3.org/2005/Atom">
    <title type="text">blabla.xml</title>
    <summary type="text">Summarize summarize…</summary>
    <content type="text/xml">
        <myxml xmlns="">blabla</myxml>
    </content>
    <object xmlns="http://docs.oasis-open.org/ns/cmis/core/200901">
        <properties>
            <propertyString xmlns:axis2ns1="http://docs.oasis-open.org/ns/cmis/core/200901"
                            axis2ns1:name="ObjectTypeId">
                <value>document</value>
            </propertyString>
        </properties>
    </object>
</entry>