Sunday, September 21, 2014

Upload documents to alfresco using REST Api


Upload documents to alfresco using REST Api:

Prerequisites:----- 

Following jar files are required (httpcomponents-client-4.3.4):

 commons-codec-1.6.jar
 commons-logging-1.1.3.jar
 commons-httpclient-3.1.jar
 httpcore-4.1.3.jar
 junit-4.12.0.jar

**************************************************************************
Alfresco's Login (POST) REST Api '/alfresco/service/api/login' return authentication ticket in response.

This is how authTicket will look like:  <ticket>TICKET_4b36ecaxxxxx5cdc5d782xxxxxxxxxxxx</ticket>

In the response you will get the authentication ticket, this authentication ticket will be used in all subsequent requests in order to get authenticated with alfresco.

In the subsequent request (as example given below in Test class) i am trying to upload a file to alfresco using REST URI::

'/alfresco/service/api/upload?alf_ticket=TICKET_4b36ecaxxxxx5cdc5d782xxxxxxxxxxxx'

Here i am passing alf_ticket as a parameter with the 'authentication ticket' value which i got from '/alfresco/service/api/login' REST call.

For more details visit: http://docs.alfresco.com/5.0/references/RESTful-intro.html

**************************************************************************

1- HttpUtils

/*
 * Created By: Abhinav Kumar Mishra
 * Copyright &copy; 2014. Abhinav Kumar Mishra.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.ParseException;

/**
 * The Class HttpUtils.
 *
 * @author Abhinav Kumar Mishra
 * @since 2014
 */
public final class HttpUtils {
 
 /** The Constant logger. */
 private static final Log LOG = LogFactory.getLog(HttpUtils.class);
 
 /**
  * Gets the login response.
  *
  * @param authURI the path
  * @param username the username
  * @param password the password
  * @return the login response
  * @throws ParseException the parse exception
  * @throws IOException Signals that an I/O exception has occurred.
  */
 public Map<String, String> getAuthResponse(final String authURI,
   final String username, final String password)
   throws ParseException, IOException {
  
  LOG.info("Authenticating request..");
  final Map<String, String> responseMap = new ConcurrentHashMap<String, String>();
  GetMethod getRequest = null;
  try {
   final HttpClient httpclient = new HttpClient();
   getRequest = new GetMethod(getAuthURL(authURI, username, password));
   final int statusCode = httpclient.executeMethod(getRequest);
   LOG.info("Auth Response Status: "+ statusCode+"|"+ getRequest.getStatusText());
 
   responseMap.put(Constants.RESP_BODY, getRequest.getResponseBodyAsString());
   responseMap.put(Constants.CONTENT_TYPE, getRequest.getResponseHeader(Constants.CONTENT_TYPE_HDR).getValue());
   responseMap.put(Constants.STATUS_CODE, String.valueOf(statusCode));
   
  } finally {
   if(getRequest!=null){
    getRequest.releaseConnection();
   }
  }
  return responseMap;
 }
 
  
 /**
  * Gets the auth ticket.
  *
  * @param authURI the auth uri
  * @param username the username
  * @param password the password
  * @return the auth ticket
  * @throws IOException Signals that an I/O exception has occurred.
  */
 public String getAuthTicket(final String authURI,
   final String username, final String password) throws IOException {
  final Map<String, String> responseMap = getAuthResponse(authURI, username, password);
  final String ticketFrmResponse = responseMap.get(Constants.RESP_BODY);
  final int startindex = ticketFrmResponse.indexOf("TICKET");
  final int endindex = ticketFrmResponse.indexOf("</");
  return ticketFrmResponse.substring(startindex, endindex);
 }
 

 /**
  * Document upload.
  *
  * @param docFileObj the doc file obj
  * @param authTicket the auth ticket
  * @param uploadURI the upload uri
  * @param siteID the site id
  * @param uploadDir the upload dir
  * @return the string
  * @throws IOException Signals that an I/O exception has occurred.
  */
 public String documentUpload(final File docFileObj,
   final String authTicket, final String uploadURI,
   final String siteID, final String uploadDir) throws IOException {

  String uploadResponse = Constants.EMPTY;
  PostMethod postRequest = null;
  try {
   final String uploadURL = getFileUploadURL(uploadURI,authTicket);
   
   LOG.info("documentUpload() | Upload URL: " + uploadURL);
   
   final HttpClient httpClient = new HttpClient();
   postRequest = new PostMethod(uploadURL);
      final String mimeType = getMimeType(docFileObj);
   final String docName = docFileObj.getName();
   LOG.info("documentUpload() | Uploading document: "+docName+" , content-type: "+mimeType);

   //To always replace the file then end following parameters in parts array
   //uploaddirectory can accept a folder name or a folder path. Do not include documentLibrary in the path 
   final Part[] parts = {
     new FilePart("filedata", docName, docFileObj, mimeType,null),
     new StringPart("filename", docName),
     new StringPart("overwrite", "true"),
     new StringPart("siteid",siteID),
     new StringPart("containerid","documentLibrary"),
     new StringPart("uploaddirectory",uploadDir)
  };
  
   postRequest.setRequestEntity(new MultipartRequestEntity(parts, postRequest.getParams()));
   
   final int statusCode = httpClient.executeMethod(postRequest); 
   
   uploadResponse = postRequest.getResponseBodyAsString();
   LOG.info("documentUpload() | Upload status: "+statusCode+"  \nUpload response: "+uploadResponse);
  
  } finally{
   if(postRequest!=null){
    //releaseConnection http connection
    postRequest.releaseConnection();
   }
  }
  return uploadResponse;
 }

 /**
  * Gets the auth url.
  *
  * @param path the path
  * @param username the username
  * @param password the password
  * @return the url
  */
 private String getAuthURL(final String path, final String username,
   final String password) {
  final StringBuffer urlStrb = new StringBuffer(path);
  urlStrb.append(Constants.QUES);
  urlStrb.append(Constants.U);
  urlStrb.append(Constants.EQL);
  urlStrb.append(username);
  urlStrb.append(Constants.AMPERSND);
  urlStrb.append(Constants.PW);
  urlStrb.append(Constants.EQL);
  urlStrb.append(password);
  return urlStrb.toString();
 }
 
 
 /**
  * Url file upload.
  *
  * @param path the path
  * @param ticket the ticket
  * @return the string
  */
 private String getFileUploadURL(final String path, final String ticket) {
  final StringBuffer urlStrb = new StringBuffer(path);
  urlStrb.append(Constants.QUES);
  urlStrb.append(Constants.TICKET_QRY);
  urlStrb.append(Constants.EQL);
  urlStrb.append(ticket);
  return urlStrb.toString();
 }
 
 /**
  * Gets the mime type.
  *
  * @param fileObj the file obj
  * @return the mime type
  * @throws IOException Signals that an I/O exception has occurred.
  */
 public String getMimeType(final File fileObj) throws IOException {
  final Path source = Paths.get(fileObj.getPath());
  return Files.probeContentType(source);
 }
}


2- Constants:

/*
 * Created By: Abhinav Kumar Mishra
 * Copyright &copy; 2014. Abhinav Kumar Mishra.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * The Class Constants.
 */
public final class Constants{

 /** The Constant EMPTY. */
 public static final String EMPTY = "";

 /** The Constant BR. */
 public static final String BR = "\n";

 /** The Constant SERVER. */
 public static final String SERVER = "server";

 /** The Constant BASEPATH. */
 public static final String BASEPATH = "baseurl";

 /** The Constant LOGIN_PATH. */
 public static final String LOGIN_PATH = "authURI";

 /** The Constant UPLOAD_PATH. */
 public static final String UPLOAD_PATH = "uploadURI";

 /** The Constant INPUT_PATH. */
 public static final String INPUT_PATH = "inputPath";

 /** The Constant DESC. */
 public static final String DESC = "description";

 /** The Constant U. */
 public static final String U = "u";

 /** The Constant PW. */
 public static final String PW = "pw";

 /** The Constant USERNAME. */
 public static final String USERNAME = "username";

 /** The Constant PASSWORD. */
 public static final String PASSWORD = "password";

 /** The Constant ENCODING. */
 public static final String ENCODING = "UTF-8";

 /** The Constant SERVER_ERR. */
 public static final String SERVER_ERR = "500";

 /** The Constant EQL. */
 public static final String EQL = "=";

 /** The Constant QUES. */
 public static final String QUES = "?";

 /** The Constant AMPERSND. */
 public static final String AMPERSND = "&";

 /** The Constant RESP_BODY. */
 public static final String RESP_BODY = "responsebody";

 /** The Constant CONTENT_TYPE. */
 public static final String CONTENT_TYPE = "content-type";

 /** The Constant STATUS_CODE. */
 public static final String STATUS_CODE = "statuscode";

 /** The Constant CONTENT_TYPE_HDR. */
 public static final String CONTENT_TYPE_HDR = "Content-Type";

 /** The Constant MIME_TYPE. */
 public static final String MIME_TYPE = "application/json";

 /** The Constant GLOBAL_PROPERTIESFILE. */
 public static final String GLOBAL_PROPERTIESFILE = "config.properties";

 /** The Constant TICKET_QRY. */
 public static final String TICKET_QRY = "alf_ticket";

 /** The Constant SITE_ID. */
 public static final String SITE_ID = "siteid";

 /** The Constant CONTAINER_ID. */
 public static final String CONTAINER_ID = "containerid";

 /** The Constant UPLOAD_DIR. */
 public static final String UPLOAD_DIR = "uploaddirectory";

}

3- Directory utility class

/*
 * Created By: Abhinav Kumar Mishra
 * Copyright &copy; 2014. Abhinav Kumar Mishra.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;


/**
 * This class DirectoryTraverser.<br/>
 * It returns set of files by traversing directories recursively.
 *
 * @author Abhinav Kumar Mishra
 * @since 2014
 */
public final class DirectoryTraverser {

 /**
  * Gets the file uris.
  *
  * @param startDir the start dir
  * @return the file uris
  * @throws FileNotFoundException the file not found exception
  */
 public static Set<File> getFileUris(final File startDir) throws FileNotFoundException {
  checkDirectories(startDir); // throw exception if not valid.
  return getUrisRecursive(startDir);
 }

 /**
  * Gets the uris recursive.<br/>
  * Recursively traverse each directory and uris of files.
  *
  * @param startDir the a starting dir
  * @return the uris recursive
  * @throws FileNotFoundException the file not found exception
  */
  private static Set<File> getUrisRecursive(final File startDir) throws FileNotFoundException {
 final Set<File> sortedSetOfFiles = new HashSet<File>();
 final File[] filesAndDirs = startDir.listFiles();
 final List<File> filesDirs = Arrays.asList(filesAndDirs);
 final Iterator<File> filesDirsItr = filesDirs.iterator();
 while (filesDirsItr.hasNext()) {
  final File file = filesDirsItr.next();
  sortedSetOfFiles.add(file); // Add files and directory URIs both
  // If uri is a directory the revisit it recursively.
  if (!file.isFile()) {
   // Call 'getUrisRecursive' to extract uris from directory
   final Set<File> innerSet = getUrisRecursive(file);
   sortedSetOfFiles.addAll(innerSet);
  }
 }

 return sortedSetOfFiles;
 }




/**
  * Checks if is valid directory.<br/>
  * If directory exists then it is valid. If directory is valid then it can
  * be read.
  *
  * @param directoryUri the a directory
  * @throws FileNotFoundException the file not found exception
  */
  private static void checkDirectories(final File directoryUri) throws FileNotFoundException {
   if (directoryUri == null) {
    throw new IllegalArgumentException("Directory should not be null.");
   }if (!directoryUri.exists()) {
    throw new FileNotFoundException("Directory does not exist: "+ directoryUri);
   }if (!directoryUri.isDirectory()) {
    throw new IllegalArgumentException("Is not a directory: "+ directoryUri);
   }if (!directoryUri.canRead()) {
    throw new IllegalArgumentException("Directory cannot be read: "+ directoryUri);
   }
 }

  private DirectoryTraverser() {
  super();
  }
}


4- Test

/*
 * Created By: Abhinav Kumar Mishra
 * Copyright &copy; 2014. Abhinav Kumar Mishra.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import junit.framework.TestCase;

/**
 * The Class UploadDocumentHttpTest.
 *
 * @author Abhinav Kumar Mishra
 * @since 2014
 */
public class UploadDocumentHttpTest extends TestCase{

 /**
  * Test document upload.
  *
  * @throws IOException Signals that an I/O exception has occurred.
  */
 @Test
 public void testDocumentUpload() throws IOException {
  final String uploadURI = "http://127.0.0.1:8080/alfresco/service/api/upload";
  final String authURI =  "http://127.0.0.1:8080/alfresco/service/api/login";
  final String username = "admin";
  final String password = "admin";
  final String inputUri = "C:/Users/Abhi/Desktop/data"; // files to be uploaded from this directory
  final String siteID = "testpoc"; //id of the site for e.g if site name is TestPoc the id will be testpoc
  final String uploadDir = "testUpload"; //directory created under document library
  
  final HttpUtils httpUtils = new HttpUtils();
  String authTicket = Constants.EMPTY;
  try {

    // Get the authentication ticket from alfresco.
    //This authTicket will be used in all subsequent requests in order to get authenticated with alfresco.
   // e.g TICKET_4b36ecaxxxxx5cdc5d782xxxxxxxxxxxx

   authTicket = httpUtils.getAuthTicket(authURI, username, password);
  } catch (IOException e) {
   e.printStackTrace();
  }

  final StringBuffer responseBody= new StringBuffer();

  final File fileObject = new File (inputUri);
  //if uri is a directory the upload all files..
  if(fileObject.isDirectory()){
   final Set<File> setOfFiles = DirectoryTraverser.getFileUris(fileObject);
   for (Iterator<File> iterator = setOfFiles.iterator(); iterator.hasNext();) {
    final File fileObj = iterator.next();
    //call document upload
    if(fileObj.isFile()){
     responseBody.append(httpUtils.documentUpload(
       fileObj, authTicket, uploadURI, siteID,
       uploadDir));
     responseBody.append(Constants.BR);
    }
       }
  }else{
   responseBody.append(httpUtils.documentUpload(
     fileObject, authTicket, uploadURI, siteID,
     uploadDir));
  }

  System.out.println("Response of upload operation >>>: "+responseBody);
  assertEquals(true, responseBody.toString().contains("File uploaded successfully"));
 }
}



Further implementations:

If you want to upload a new version of already existing file, you just have to get the nodeRef of existing file and pass below given parts parameter to same Upload REST API call. See documentUpload method above, I have highlighted the parts parameter. You have to replace the parts parameter and upload the file.

// To upload the file as a new version once the file was uploaded, then send following parameters in 
// parts array. Note that we have to remove the "override" parameter from the parts array and add 
// "updateNodeRef" parameter.
 //uploaddirectory can accept a folder name or a folder path. Do not include documentLibrary in the path 
final Part[] partsUploadAsVersion = {
     new FilePart("filedata", docName, docFileObj, mimeType,null),
     new StringPart("filename", docName),
     new StringPart("siteid",siteID),
     new StringPart("containerid","documentLibrary"),
     new StringPart("uploaddirectory",uploadDir), //Optional Parameter
    new StringPart("updateNodeRef ", nodeRefOfExistingFile) 
  };

Note:- You will still need the old parts array to upload the file for the first time. Once file is uploaded then to upload new version of that file (node) you have to use above given option.

If you want to upload file to a target destination for example: 'Shared' folder in the alfresco repository, then you can use the destination parameter to pass the nodeRef and additionally pass the folder name inside the destination node.

Here is the sample:

final Part[] partsUploadAsVersion = {
     new FilePart("filedata", docName, docFileObj, mimeType,null),
     new StringPart("filename", docName),
     new StringPart("destination", destinationNodeRef), // nodeRef of 'Shared' folder i.e. workspace://SpacesStore/85d2a84d-271b-41b1-9449-02f5942893a0
     new StringPart("uploaddirectory",uploadDir), //Optional Parameter
    new StringPart("overwrite ", "true") 
  };


Here is the detailed description for upload api:

Upload file content and meta-data into repository.


POST /alfresco/service/api/upload

 

HTML form data
  • filedata, (mandatory) HTML type file
  • You must specify one of:
    • destination (the folder NodeRef where the node will be created)
    • updateNodeRef (the NodeRef of an existing node that will be updated)
    • siteid and containerid (the Site name and the container in that site where the document will be created)
  • uploaddirectory - name of the folder (either in the site container or the destination) where the document will be uploaded. This folder must already exist
  • description - Description for a version update (versionDescription)
  • contenttype - The content type that this document should be specialised to
  • majorversion
  • overwrite
  • thumbnails
Return content
  • nodeRef

Return status: STATUS_OK (200)

The web script description document specifies the following options:
ValueDescription
jsonThe default response format
userThe authentication access
requiredThe transaction level
anyThe format style

----------------------------------------------------------------------------------------------------------------------
If you want to download or delete a node/file then you can write a piece of code taking the reference of above code to download/delete the node/file.

REST API for download file/node is: (It should be HTTP Get request)

GET /alfresco/service/api/node/content/{store_type}/{store_id}/{id}?a=false&alf_ticket={TICKET}

Example:

http://127.0.0.1:8080/alfresco/service/api/node/content/workspace/SpacesStore/85d2a84d-271b-41b1-9449-02f5942893a0?a=false&alf_ticket=TICKET_5550fa5e9b87bead8f008e906185e023b7ce21ed

Where: 
a: means attach. if true, force download of content as attachment. Possible values are true/false
store_type: workspace
store_id: SpacesStore
id: nodeRefId (UUID of the node)

A StoreRef is comprised of:

Store Protocol - that is, the type of store
Store Identifier - the id of the store

Example storeRefs are:

workspace://SpacesStore  (store_type://store_id)
version://versionStore  (store_type://store_id)
archive://SpacesStore  (store_type://store_id)

For more on Download Services visit my another post here: Downloading Content From Alfresco

--------------------------------------------------------------------------------------------------------------------------------


REST API for delete file/node is (It should be HTTP Delete request)

DELETE /alfresco/service/api/node/{store_type}/{store_id}/{id}?alf_ticket={TICKET}

Example:
http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/0a1b9c30-39a6-4249-8f2b-78c4e8b29b2c?alf_ticket=TICKET_5550fa5e9b87bead8f008e906185e023b7ce21ed

Note: You need to pass alf_ticket as a parameter for very REST call. You can see, i am adding alf_ticket parameter for upload, download and delete examples above.

Refer to Repository REST API references:

https://docs.alfresco.com/5.0/references/RESTful-Repository.html





24 comments:

  1. DirectoryTraverser.java the file is missing :( and the code wont compile and work is there any possibility to add that class ??

    ReplyDelete
  2. You could also use directory walker or fileutils availble in commons-io.

    Only thing is that you should be able get file path as a input for further action.

    I have Added that class for you. You can use it.

    ReplyDelete
    Replies
    1. Thank you. Appreciate it. It will help a lot of people.

      Delete
  3. I am getting index out of bounds exception while running this code as the response obtained is very large in size(it gives entire post login page) I want to know what exactly is the token expected by "authTicket" which is passed ahead?

    ReplyDelete
    Replies
    1. It is authentication token which you get after login. Refer Below API : http://docs.alfresco.com/community5.0/references/RESTful-RepositoryLoginPost.html

      In response to login REST call you will get alf_ticket.

      Delete
  4. Can you please provide code for download and delete files from alfresco?

    ReplyDelete
    Replies
    1. REST API for download file/node is: (It should be HTTP Delete request)

      DELETE /alfresco/service/api/node/{store_type}/{store_id}/{id}?alf_ticket={TICKET}

      Example:
      http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/0a1b9c30-39a6-4249-8f2b-78c4e8b29b2c?alf_ticket=TICKET_5550fa5e9b87bead8f008e906185e023b7ce21ed

      Delete
    2. REST API for download file/node is: (It should be HTTP Get request)

      GET /alfresco/service/api/node/{store_type}/{store_id}/{id}/content/{fileName}?c=force&a=false&alf_ticket={TICKET}

      Example:
      http://127.0.0.1:8080/alfresco/service/api/node/workspace/SpacesStore/0a1b9c30-39a6-4249-8f2b-78c4e8b29b2c/content/profile_pic.jpg?c=force&a=false&alf_ticket=TICKET_5550fa5e9b87bead8f008e906185e023b7ce21ed

      Delete
  5. I really appriciate for sharing and helping cuz even i am facing issuess for uploading and downloading document it would be more helpful if you provide a bit documentation where to use which code i mean complete project folder directory structure but really it's gonna help me

    ReplyDelete
    Replies
    1. Could you please send the details about the error you are getting ? I have given examples of the URLs above, but not sure where you are finding it difficult.

      Delete
  6. Hi ,

    I am getting the Forbidden response while getting the login ticket.

    please help me.>>

    ReplyDelete
    Replies
    1. Hi Ganna

      Can you provide the steps you did ? provide the end point url and payload details as well. I can verify it.


      Regards
      Abhinav

      Delete
    2. Here is the REST API documentation:

      GET Login: http://docs.alfresco.com/5.0/references/RESTful-RepositoryLoginGet.html
      POST Login: http://docs.alfresco.com/5.0/references/RESTful-RepositoryLoginPost.html


      Send the steps though if you are still getting issue.

      Delete
  7. Hai,

    i need to develop "Delete Document from alfresco using RestAPI webservices. i am getting some issues can you please suggest me how delete document from alfresco Site through RestAPI.

    @RequestMapping(value="/deleteFiles", method=RequestMethod.DELETE)
    public void getDeleteFiles(HttpServletResponse response,@RequestParam String siteName,@RequestParam String userid,@RequestParam String password,@RequestParam String downloadDocumentPath) {
    try {
    String fileName = null;
    System.out.println("delete starting-------------------------");
    String urlString = "";
    String destination = null;
    LOG.info("siteName :"+siteName);
    LOG.info("userid :"+userid);
    LOG.info("password :"+password);
    LOG.info("deleteDocumentPath :"+deleteDocumentPath);

    fileName = deleteDocumentPath.substring(deleteDocumentPath.lastIndexOf("/") + 1);

    urlString = Constants.RestURLS.DELETREURL + URLEncoder.encode(siteName, "UTF-8")
    + Constants.RestURLS.SLASH +"documentLibrary"+ Constants.RestURLS.SLASH + URLEncoder.encode(deleteDocumentPath, "UTF-8");
    LOG.info("get the Node getDownloadFiles ref URL:::::::::::::::::::::::::::::::::::::::::::"
    + urlString);
    String jsonresponse=null;
    jsonresponse = HttpClientUtils.getResponseByHttpClient(urlString, userid, password, "");
    System.out.println("Document deleted sucessfully");
    // int statusCode = client.executeMethod(method);
    } catch (Exception e) {
    // TODO: handle exception
    e.printStackTrace();
    }
    }



    and this is the RestURLS
    public static class RestURLS
    {
    public static String UPLOADURL="http://localhost:80/alfresco/service/api/upload?alf_ticket=";
    public static String GETNODEREFURL="http://localhost:80/alfresco/service/getNodeRef?folderPath=Sites/";
    public static String DOWNLOADURL="http://localhost:80/alfresco/service/api/node/content/workspace/SpacesStore/";

    //public static String SLASH="/";

    public static String SLASH="/";
    public static String NEWLINE="\n";
    public static String IPNUMBER="localhost";
    public static int PORTNUMBER=80;
    public static String USERNAME="sandeep";
    public static String PASSWORD="sandeep";


    }


    }

    ReplyDelete
    Replies
    1. Hi Sandeep
      Could you send me the error you are getting ?

      Delete
    2. Here are the steps to delete the document from Alfresco via OOTB REST API:

      1- Get the authentication ticket from alfresco using Login REST API

      GET Login: http://docs.alfresco.com/5.0/references/RESTful-RepositoryLoginGet.html
      POST Login: http://docs.alfresco.com/5.0/references/RESTful-RepositoryLoginPost.html

      e.g. http://localhost:8080/alfresco/service/api/login?u=admin&pw=admin

      You will get a ticket in the json response. Parse the JSON response and take out the alf_ticket value for further usage.

      This is how authTicket will look like: TICKET_4b36ecaxxxxx5cdc5d782xxxxxxxxxxxx

      2- Once you have ticket, prepare a delete URL for the document you want to delete.

      URL Format should be like: http://localhost:8080/alfresco/service/api/node/{store_type}/{store_id}/{id}?alf_ticket={TICKET}

      where:

      store_type: workspace
      store_id: SpacesStore
      id: nodeRefId (UUID of the node)
      alf_ticket: The authentication ticket you got as part of first step.

      So for example if your document nodeRef in alfresco repository is workspace://SpacesStore/5cee9f74-eb2a-43a4-965d-6e4fcde4fb9e

      Then the Delete URL would be: http://localhost:8080/alfresco/service/api/node/workspace/SpacesStore/5cee9f74-eb2a-43a4-965d-6e4fcde4fb9e?alf_ticket=TICKET_4b36ecaxxxxx5cdc5d782xxxxxxxxxxxx

      3- Once you are done preparing the URL for the node, then you need to make a DETELE (HTTP Request) to alfresco for the above prepared URL.

      Hope this helps.

      Delete
    3. Sample code:
      private static final String AUTH_URI = "/alfresco/service/api/login";
      private static final String SERVER_ENDPOINT = "http://localhost:8080";


      public String getAuthTicket(final String userName, final String password)
      throws ClientProtocolException, IOException, AlfScriptException {
      LOG.info("Getting auth ticket for user: "+userName);
      String alfTicket = StringUtils.EMPTY;
      final Map authPayload = new ConcurrentHashMap();
      authPayload.put(AlfScriptConstants.PARAM_USER, userName);
      authPayload.put(AlfScriptConstants.PARAM_PASSWORD, password);
      final ObjectMapper objMapper = new ObjectMapper();
      objMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
      objMapper.enable(SerializationFeature.INDENT_OUTPUT); //Indent the output
      final String mapAsJson = objMapper.writeValueAsString(authPayload);

      final CloseableHttpClient httpclient = HttpClientBuilder.create().build();
      final HttpPost httpPost = new HttpPost(SERVER_ENDPOINT+AUTH_URI);
      final StringEntity httpEntity = new StringEntity(mapAsJson);
      httpEntity.setContentType(MIME_JSON);
      httpPost.setEntity(httpEntity);

      final HttpResponse httpResp = httpclient.execute(httpPost);
      final StatusLine status = httpResp.getStatusLine();
      final int statusCode = status.getStatusCode();
      final String statusMsg = status.getReasonPhrase();
      LOG.info("Status: "+statusCode +" | "+ statusMsg);
      if (statusCode == 200) {
      final String resonseStr = IOUtils.toString(httpResp.getEntity().getContent(),
      StandardCharsets.UTF_8);
      final JSONObject jsonObj = new JSONObject(resonseStr);
      final JSONObject data = (JSONObject) jsonObj.get("data");
      alfTicket = data.getString("ticket");
      } else {
      throw new AlfScriptException(statusMsg);
      }
      return alfTicket;
      }


      public void deleteNode(final String authTicket, final String deleteNodeUri)
      throws URISyntaxException, JsonProcessingException,
      ClientProtocolException, UserReportException, IOException {
      // example of deleteNodeUri : /alfresco/service/api/node/workspace/SpacesStore/5cee9f74-eb2a-43a4-965d-6e4fcde4fb9e
      final URIBuilder uriBuilder = new URIBuilder(SERVER_ENDPOINT + deleteNodeUri);
      uriBuilder.addParameter("alf_ticket", authTicket);

      final CloseableHttpClient httpclient = HttpClientBuilder.create().build();
      final HttpDelete httpDelete = new HttpDelete(uriBuilder.toString());
      final HttpResponse httpResp = httpclient.execute(httpDelete);
      final StatusLine status = httpResp.getStatusLine();
      final int statusCode = status.getStatusCode();
      final String statusMsg = status.getReasonPhrase();
      LOG.info("Status: "+statusCode +" | "+ statusMsg);
      }

      Delete
  8. Hello, thanks for your great job.
    I need your help, i got this error when i try to delete file in alfresco with your example :
    java.lang.NoSuchFieldError: INSTANCE
    javax.faces.FacesException:.........java.lang.NoSuchFieldError: INSTANCE

    I don't understand this error

    ReplyDelete
  9. Hi,

    We are currently using Alfresco v 5.2 that we have deployed on a Tomcat server.

    We are using the v0 web script as shown below

    Share Search Component Data Webscript
    /slingshot/search?term={term?}&tag={tag?}&site={site?}&container={container?}&sort={sort?}&query={query?}&repo={repo?}

    The query param dosen't work (for me)==> always bad request
    But, when I use the term param, the service work as expected.

    ReplyDelete
    Replies
    1. I'd suggest to use search rest api v1. See docs here:
      https://hub.alfresco.com/t5/alfresco-content-services-blog/v1-rest-api-part-9-queries-search/ba-p/287736
      https://docs.alfresco.com/5.2/pra/1/topics/pra-welcome.html

      Delete
  10. Hi, where can i find and download the required jar files?

    ReplyDelete
    Replies
    1. You can always go to this repository and search for them : https://mvnrepository.com/

      Delete
  11. First of all thanks for the support you provide, I have a problem and it shows me this message javax.servlet.ServletException: java.lang.NoClassDefFoundError: org/apache/commons/httpclient/HttpMethod it seems that it is not finding the class, but in my project If I have imported the commons-httpclient-3.1.jar library, any suggestions? Sorry for the English, I'm using a translator

    ReplyDelete
    Replies
    1. java.lang.NoClassDefFoundError indicates that the HttpMethod class file was not found at run time. Please make sure you copy all the jar files to your container library.

      Delete

Thanks for your comments/Suggestions.