Apex Dynamic Object Mapping for REST endpoints

Writing rest endpoints in Apex can be hard and exposing Salesforce fields to external application may not make allot of sense as custom fields end with __c and some fields are not writable or systems fields. I have worked on creating a Serializer that could serialize a Salesforce object mapping and translate that back to a Salesforce SObject.

Let say you can provide an endpoint to an app that could return the metadata of that object as well as the list of fields it expects. The mapping shows a map of keys and values. The keys are the Salesforce SObject fields and the values are the fields exposed to external application.

{
  "serializeNulls": true,
  "mapKeysFlag": true,
  "mapKeys": {
    "responseCode": "responseCode",
    "result": "result",
    "userId": "userId",
    "size": "size",
    "status": "status"
  },
  "userId": "00536000000erTFAAY",
  "result": {
    "external_id__c": "externalid",
    "sicdesc": "sicdesc",
    "accountsource": "accountsource",
    "site": "site",
    "rating": "rating",
    "description": "description",
    "tickersymbol": "tickersymbol",
    "ownership": "ownership",
    "numberofemployees": "numberofemployees",
    "billingcountry": "billingcountry",
    "billingpostalcode": "billingpostalcode",
    "billingstate": "billingstate",
    "billingcity": "billingcity",
    "billingstreet": "billingstreet",
    "parentid": "parentid",
    "type": "type",
    "name": "name",
    "id": "id"
  }
}

An application can send us data in the following way and we can serialize it to the Account sObject without doing any mapping.

{"externalid":"2333", "photourl": "http://blah.com", "website": "http://web.com", "accountnumber": "3243232", "fax": "2343432", "phone": "32222"}

Define a serializer to swap the key from application with the fields of the Salesforce object

public abstract class Rest_Serializer {

		public Rest_Serializer(){}

		private Map<String,String> mapKeys;
		private boolean serializeNulls = true;
		private boolean mapKeysFlag = true;

		public Rest_Serializer(Map<String,String> mapping){
			this.mapKeys = mapping;
		}

		public void setSerializeNulls(Boolean serializeNulls){
			this.serializeNulls = serializeNulls;
		}

		public void setMapKeysFlag(Boolean mapKeysFlag){
			this.mapKeysFlag = mapKeysFlag;
		}

		public String serialize(Object obj){
			String retString = JSON.serialize(obj);
			if (retString.length() < 50000){
				retString = transformStringForSerilization(retString);
				if(serializeNulls){
					retString = removeNullsFromJSON(retString);
				}
			} else {
		//throw exception
			}
			return retString;
		}

		public Object deserialize(String jsonString, System.Type type){
			jsonString = transformStringForDeserilization(jsonString);
			Object obj = JSON.deserialize(jsonString, type);
			return obj;
		}

		private String transformStringForSerilization(String s){
			if (mapKeys!=null && mapKeysFlag){
				return replaceAll(s, mapKeys);
			}
			return s;
		}

		private String transformStringForDeserilization(String s){
			Map<String,String> flippedMap = new Map<String,String>();
			if (mapKeys!=null && mapKeysFlag){
				for(String key : mapKeys.keySet()){
					flippedMap.put(mapKeys.get(key), key);
				}
			}
			return replaceAll(s, flippedMap);
		}

		private String removeNullsFromJSON(String s){
				return s.replaceAll('("[\\w]*":null,)|(,?"[\\w]*":null)','');
		}

		private String replaceAll(String s, Map<String,String> toFromMap){
			if (mapKeys!=null && mapKeysFlag){
				for(String key : toFromMap.keySet()){
						s = s.replaceAll('"'+key+'":', '"'+toFromMap.get(key)+'":');
				}
			}
			return s;
		}

		public Boolean getSerializeNulls(){
			return serializeNulls;
		}
}

Extend the Rest Serializer to create a DynamicModel that will take all fields and serialize them to an SObject

public class DynamicModel extends Rest_Serializer {
    public DynamicModel(Map<String,String> fieldMapping){
       super(fieldMapping);
    }
}

Get model name and return SObject Fieldsfields

	public static Map<String,String> getModelByObject(String sObjectName){
		Map<String,String> replaceFieldNames = new Map<String,String>();
		SObjectType accountType = Schema.getGlobalDescribe().get(sObjectName);
		Map<String,Schema.SObjectField> mfields = accountType.getDescribe().fields.getMap();
		for (String mfield : mfields.keySet()){
			//String uField = mfield.replace('[__c,_]','');
			replaceFieldNames.put(mfield, Rest_Util.toCamelCase(mfield));
		}
		return replaceFieldNames;
	}

	public static Map<String, Schema.DescribeFieldResult> getFieldMetaData(
	  Schema.DescribeSObjectResult dsor, Set<String> fields) {
		Map<String,Schema.DescribeFieldResult> finalMap = new Map<String, Schema.DescribeFieldResult>();

	  Map<String, Schema.SObjectField> objectFields = dsor.fields.getMap();

	  for(String field : fields){
	    if (objectFields.containsKey(field)) {
	      Schema.DescribeFieldResult dr = objectFields.get(field).getDescribe();
	      finalMap.put(field, dr);
	    }
	  }
	  return finalMap;
	}

Get SObject fields for an object and translate application fields to SObject fields and return object

    global with sharing class GetModel implements Rest_Dispatcher.Dispatchable {
			private Rest_Global_Request_Json requestBody;

			global String getURIMapping(){
					return Rest_Constants.URI_SETTINGS + '/model/{objectName}';
			}

			global void setRequestBody(Rest_Global_Request_Json requestBody){
					this.requestBody = requestBody;
			}

			global Rest_Global_Json execute(Map<String, String> parameters){
					Rest_Global_Json globalJson = new Rest_Global_Json();
					String sObjectName = parameters.get('objectName');
					Map<String,String> uiFieldNamesForObject = getModelByObject(sObjectName);
					BP_JSON.DynamicModel dynamicModel = new BP_JSON.DynamicModel(uiFieldNamesForObject);
					Schema.SObjectType convertType = Schema.getGlobalDescribe().get(sObjectName);
					Type classType = Type.forName(sObjectName);
					Object transformedObject = dynamicModel.deserialize(requestBody.getRequest(), classType);
					globalJson.setResult(transformedObject);
					return globalJson;
			}

			global override String toString(){
				Rest_Endpoint.Path path = new Rest_Endpoint.Path();
				path.setPath(getURIMapping());
				Rest_Endpoint endpoint = new Rest_Endpoint(path);
				return JSON.serialize(endpoint);
			}
	}
}

Salesforce Chatter Attaching Files to SObject

There are different ways you can use salesforce to attach a file to an SObject using Chatter.

  • Apex Code
  • Chatter REST Api
    public static void createAttachmentFeed(List<Attachment> attachments){
      for (Attachment attachment : attachments){
        // ContentVersion is how you upload a file!
       ContentVersion version = new ContentVersion();
       version.Title=attachment.Name;
       version.PathOnClient = '\\' + attachment.Name;
       version.VersionData = attachment.Body;
       version.NetWorkId = brightPlanWebCustomSettings.Community_Id__c;
       insert version;

       // After you insert the ContentVersion object, a base 'ContentDocument' is established
       // The ID of the ContentDocument is what you need to attach the file to the Chatter post.
       version = [SELECT ID,ContentDocumentId FROM ContentVersion WHERE ID=:version.id];

       // Form a basic post attached to our own feed.
       ConnectApi.FeedItemInput feedItem = new ConnectApi.FeedItemInput();
       feedItem.subjectId = attachment.ParentId; // This can also be an objectID to post the file to.

       // Now connect the feeditem to our already uploaded file.
       feedItem.capabilities = new ConnectAPI.FeedElementCapabilitiesInput();
       feedItem.capabilities.files = new ConnectAPI.FilesCapabilityInput();
       feedItem.capabilities.files.items = new List<ConnectAPI.FileIdInput>();
       ConnectAPI.FileIdInput attachFile = new ConnectAPI.FileIDInput();

       //**** Here is where we attach the specific file to the post!
       attachFile.id = version.contentDocumentid;
       feedItem.capabilities.files.items.add(attachFile);

       // Execute the posting
       ConnectApi.FeedElement feedElement = ConnectApi.ChatterFeeds.postFeedElement(brightPlanWebCustomSettings.Community_Id__c, feedItem);
      }
    }

Some limitations using this is using Blob for version.VersionData = attachment.Body; will run into Apex String length exceeds maximum: 6000000.

Chatter Rest API

POST https://cs43.salesforce.com/services/data/v35.0/connect/communities/0DB63000000003jGAA/chatter/feed-elements/batch

HEADER

Authorization         Bearer {sessionToken}

Content-Type          multipart/form-data; boundary=a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq

Format is as follows:

{salesforceOrgUrl}/services/data/v35.0/connect/communities/{salesforceCommunityId}chatter/feed-elements/batch

The subjectId is the SObject Id to which you want to link the file, is this case we use our Case Id.

--a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq
Content-Type: application/json; charset=UTF-8
Content-Disposition: form-data; name="json"
{
"inputs": [
{
"binaryPartNames": [
"file1"
],
"richInput": {
"subjectId": "50063000003YlSe",
"capabilities": {
"content": {
"title": "file1.pdf"
}
},
"feedElementType": "FeedItem"
}
},
{
"binaryPartNames": [
"file2"
],
"richInput": {
"subjectId": "50063000003YlSe",
"capabilities": {
"content": {
"title": "file2.pdf"
}
},
"feedElementType": "FeedItem"
}
}
]
}
--a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Disposition: form-data; name="file1"; filename="file1.pdf"

...contents of file1.pdf...

--a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq
Content-Disposition: form-data; name="file2"; filename="file2.pdf"
Content-Type: application/octet-stream; charset=ISO-8859-1
...contents of file2.pdf...
--a7V4kRcFA8E79pivMuV2tukQ85cmNKeoEgJgq--

Benefits you can batch upload files without hitting an Apex limits.

Both the Chatter and Apex solutions can be used by Community Users to upload files.

Activiti REST Client Example

Activiti REST Client

package com.nuke.activiti.client;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.MediaType;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.ClientResource;
import org.slf4j.Logger;

/**
 * @author tmichels
 */
public class ActivitiClient {

	private static final Logger logger = org.slf4j.LoggerFactory.getLogger(NucleusClient.class);
	
	private static final String REST_URI = "http://activiti-dev.com:8090/api/activiti/v1";
	private static final String LDAP_USERNAME="xxxx";
	private static final String LDAP_PASSWORD="xxxx";
	
	private static ClientResource getClientResource(String uri) throws IOException{
		ClientResource clientResource = new ClientResource(uri);
		clientResource.setChallengeResponse(ChallengeScheme.HTTP_BASIC, LDAP_USERNAME, LDAP_PASSWORD);
        return clientResource;
	}
	
	public static List<String> getQueueNames(String username) throws JSONException, IOException{
		String authenticateUserUri = REST_URI + "/identity/users/"+username;
		Representation authenticateUserJSON = getClientResource(authenticateUserUri).get(MediaType.APPLICATION_JSON);
		JSONObject authenticateObject = new JSONObject(authenticateUserJSON.getText());
		logger.info("Get Queue Name: " + authenticateObject);
		if (!authenticateObject.opt("id").equals(null)) {
			List<String> queueForUser = new ArrayList<String>();
			String uri = REST_URI +"/repository/process-definitions";
			Representation response = getClientResource(uri).get(MediaType.APPLICATION_JSON);
			JSONObject object = new JSONObject(response.getText());
			JSONArray arr = (JSONArray) object.get("data");
			for (int i = 0; i < arr.length(); i++) {
				JSONObject ob = (JSONObject) arr.get(i);
				queueForUser.add(ob.get("name").toString());
			}
			return queueForUser;
		}
		return null;
	}

	public static String claimAndCompleteTaskByProcessIdAndActorName(String processInstanceId, String actorName) throws JSONException, IOException {
        try {
            String authenticateUserUri = REST_URI + "/identity/users/"+actorName;
            Representation authenticateUserJSON = getClientResource(authenticateUserUri).get(MediaType.APPLICATION_JSON);
            JSONObject authenticateObject = new JSONObject(authenticateUserJSON.getText());
            logger.info("AuthenticateObject: " + authenticateObject);
            if (!authenticateObject.opt("id").equals(null)) {
                String getTaskUri = REST_URI + "/runtime/tasks?candidate=" + actorName + "&size=1&order=asc&taskDefinitionKey=UnassignedLoan";
                Representation response = getClientResource(getTaskUri).get(MediaType.APPLICATION_JSON);
                JSONObject object = new JSONObject(response.getText());
                if (object != null) {
                    JSONArray arr = (JSONArray) object.get("data");
                    for (int i = 0; i < arr.length(); i++) {
                        JSONObject ob = (JSONObject) arr.get(i);
                        if (processInstanceId != null) {
                            if (ob.get("processDefinitionId").equals(processInstanceId)) {
                                logger.info("Returned task: " + ob);
                                if (ob.get("id") != null) {
                                    String claimUri = REST_URI + "/runtime/tasks/" + ob.get("id");
                                    logger.info("Claim URI: " + claimUri);
                                    JSONStringer jsAssignee = new JSONStringer();
                                    jsAssignee.object().key("assignee").value(actorName);
                                    jsAssignee.key("owner").value(actorName);
                                    jsAssignee.endObject();
                                    logger.info("jsAssignee: " + jsAssignee.toString());
                                    
                                    JSONStringer jsClaim = new JSONStringer();
                                    jsClaim.object().key("action").value("claim");
                                    jsClaim.endObject();
                                    logger.info("jsClaim: " + jsClaim.toString());
                                    
                                    JsonRepresentation jsonAssigneeRepresentation = new JsonRepresentation(jsAssignee);
                                    logger.info("jsonAssigneeRepresentation: " + jsonAssigneeRepresentation.getText());
                                    
                                    JsonRepresentation jsonClaimRepresentation = new JsonRepresentation(jsClaim);
                                    logger.info("jsonClaimRepresentation: " + jsonClaimRepresentation.getText());
                                    
                                    Representation assigneeResponse = getClientResource(claimUri).put(jsonAssigneeRepresentation);
                                    Representation claimResponse = getClientResource(claimUri).post(jsonClaimRepresentation);
                                    	
                                    logger.info("Assignee Response: " + assigneeResponse.getText());
                                    
                                    if (claimResponse.getText() == null) {
                                    	boolean completeTask = NucleusClient.completeTaskByIdWithVariables(ob.getString("description").toString(), actorName, null);
                                        logger.info("Complete Response: "  + completeTask);
                                        if (completeTask) {
                                        	 JSONObject taskByLoan = getTaskByLoanId(ob.getString("description").toString());
                                        	 JSONArray taskByLoanArray = (JSONArray) taskByLoan.get("data");
                                        	 if (!taskByLoanArray.isNull(0)) {
                                        		 JSONObject obTask = (JSONObject) taskByLoanArray.get(0);
                                            	 JSONStringer jsAssigneeAfterComplete = new JSONStringer();
                                            	 jsAssigneeAfterComplete.object().key("assignee").value(actorName);
                                            	 jsAssigneeAfterComplete.key("owner").value(actorName);
                                            	 jsAssigneeAfterComplete.endObject();
                                                 JsonRepresentation jsonAssigneeAfterCompleteRepresentation = new JsonRepresentation(jsAssigneeAfterComplete);
                                                 String claimAfterCompleteUri = REST_URI + "/runtime/tasks/" + obTask.get("id");
                                                 getClientResource(claimAfterCompleteUri).put(jsonAssigneeAfterCompleteRepresentation);
                                        	 }
                                            return ob.getString("description");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return null;
            }
            return null;
        }catch (Exception e){
        	logger.error("claimAndCompleteTaskByProcessIdAndActorName", e);
            return null;
        }
	}
	
	public static JSONObject getTaskByLoanId(String loanId) throws JSONException, IOException {
		String getTaskByLoanId = REST_URI +"/runtime/tasks?description=" + loanId + "&size=1";
        Representation response = getClientResource(getTaskByLoanId).get(MediaType.APPLICATION_JSON);
        JSONObject object = new JSONObject(response.getText());
        return object;
	}
	
	public static boolean completeTaskByIdWithVariables(String loanId, String actorName, Map<String, String> completeVariables) throws Exception {
        try {
            JSONObject loanjsonObjs = getTaskByLoanId(loanId);
            JSONArray loanArr = (JSONArray) loanjsonObjs.get("data");
            logger.info("LoanArr: " + loanArr);
            if (!loanArr.isNull(0) && loanArr.getJSONObject(0).has("id")) {
              JSONObject loanjsonObj = loanArr.getJSONObject(0);
          	  String uri = REST_URI + "/runtime/tasks/" + loanjsonObj.get("id").toString();

                JSONStringer jsComplete = new JSONStringer();
                jsComplete.object().key("action").value("complete");
              
                if (completeVariables!=null){
                    jsComplete.key("variables").array().object();
                    for (String completeVariable : completeVariables.keySet()) {
                        jsComplete.key("name").value(completeVariable).key("value").value(completeVariables.get(completeVariable));
                    }
                    jsComplete.endObject().endArray();
                }

                jsComplete.endObject();

                JsonRepresentation jsonCompleteRepresentation = new JsonRepresentation(jsComplete);
                logger.info("jsonCompleteRepresentation: " + jsonCompleteRepresentation.getText());
                if(completeVariables==null || !(loanArr.getJSONObject(0).getString("taskDefinitionKey").equals("SaveForLater") && completeVariables.get("disposition").equals("saveforlater"))) {
                	Representation completeResponse = getClientResource(uri).post(jsonCompleteRepresentation, MediaType.APPLICATION_JSON);
                	logger.info("Complete Response: " + completeResponse.getText());
                    if (completeResponse.getText()==null){
                    	if (completeVariables!=null && !completeVariables.get("disposition").equals("incomplete")) {
                    		 JSONObject taskByLoan = getTaskByLoanId(loanId);
                        	 JSONArray taskByLoanArray = (JSONArray) taskByLoan.get("data");
                        	 
                        	 if (!taskByLoanArray.isNull(0)) {
                        		 JSONObject obTask = (JSONObject) taskByLoanArray.get(0);
                         
                            	 JSONStringer jsAssigneeAfterComplete = new JSONStringer();
                            	 jsAssigneeAfterComplete.object().key("assignee").value(actorName);
                            	 jsAssigneeAfterComplete.key("owner").value(actorName);
                            	 jsAssigneeAfterComplete.endObject();
                                
                                 JsonRepresentation jsonAssigneeAfterCompleteRepresentation = new JsonRepresentation(jsAssigneeAfterComplete);
                                 String claimAfterCompleteUri = REST_URI + "/runtime/tasks/" + obTask.get("id");
                                 getClientResource(claimAfterCompleteUri).put(jsonAssigneeAfterCompleteRepresentation);
                        	 }
                    	}
                        return true;
                    }
                } else {
                	return true;
                }
            }
        }catch (Exception e){
          	e.printStackTrace();
              
        }
        return false;
	}
	
	public static String getProcessIdByName(String queueName) throws IOException, JSONException {
		String uri = REST_URI + "/repository/process-definitions";
		Representation response = getClientResource(uri).get(MediaType.APPLICATION_JSON);
		JSONObject object = new JSONObject(response.getText());
		if (object != null) {
			JSONArray arr = (JSONArray) object.get("data");
			for (int i = 0; i < arr.length(); i++) {
				JSONObject jsonObject = (JSONObject) arr.get(i);
				if (jsonObject.get("key").equals(queueName)) {
					logger.info("Returning processDefinitionId " + jsonObject.get("id"));
					return (String) jsonObject.get("id");
				}
			}
		}
		return null;
	}

	public static String createTaskByProcessId(String processDefinitionId, Map<String, String> taskVariables) throws Exception {
		String uri = REST_URI + "/runtime/process-instances";
		JSONStringer jsRequest = new JSONStringer();
		jsRequest.object().key("processDefinitionId").value(processDefinitionId).key("variables").array().object();
		for (String taskVariable : taskVariables.keySet()) {
			jsRequest.key("name").value(taskVariable).key("value").value(taskVariables.get(taskVariable));
		}
		jsRequest.endObject().endArray();
		jsRequest.endObject();
		Representation rep = new StringRepresentation(jsRequest.toString(), MediaType.APPLICATION_JSON);
		JSONObject jsObj = new JSONObject(getClientResource(uri).post(rep).getText());
		logger.info("Returned process: " + jsObj);
		if (jsObj.has("id")) {
			return  jsObj.getString("id");
		} else {
			return null;
		}
	}

	public static String getTaskIdByProcessIdAndActorName(String processInstanceId, String actorName) throws Exception {
		String uri = REST_URI + "/runtime/tasks?candidate=" +actorName;
		Representation response = getClientResource(uri).get(MediaType.APPLICATION_JSON);
		JSONObject object = new JSONObject(response.getText());
		if (object != null) {
			JSONArray arr = (JSONArray) object.get("data");
			for (int i = 0; i < arr.length(); i++) {
				JSONObject ob = (JSONObject) arr.get(i);
				if (ob.get("processDefinitionId").equals(processInstanceId)) {
					logger.info("Returned task: " + ob);
					logger.info("Returning taskId " + ob.get("id"));
					return (String) ob.get("id");
				}
			}
		}
		return null;
	}

	public static boolean claimTaskByIdAndActorName(String taskId, String actorName) throws Exception {
		String uri = REST_URI + "/runtime/tasks/" + taskId;

        JSONStringer jsClaim = new JSONStringer();
        jsClaim.object().key("action").value("claim");
        jsClaim.endObject();
        logger.info("jsClaim: " + jsClaim.toString());

        JsonRepresentation jsonClaimRepresentation = new JsonRepresentation(jsClaim);
        logger.info("jsonClaimRepresentation: " + jsonClaimRepresentation.getText());
		Representation claimResponse = getClientResource(uri).post(jsonClaimRepresentation, MediaType.APPLICATION_JSON);

        JSONStringer jsAssignee = new JSONStringer();
        jsAssignee.object().key("assignee").value(actorName);
        jsAssignee.key("owner").value(actorName);
        jsAssignee.endObject();
        logger.info("jsAssignee: " + jsAssignee.toString());
        
        JsonRepresentation jsonAssignRepresentation = new JsonRepresentation(jsAssignee);

        getClientResource(uri).put(jsonAssignRepresentation, MediaType.APPLICATION_JSON);

        return claimResponse.getText()==null;
	}


	@SuppressWarnings("unused")
	public static int getTaskCountByActorNameAndStatus(String actorName, String status) throws Exception {
		String uri = REST_URI + "/runtime/tasks?candidate=" + actorName + "&status=" + status;
		Representation response = getClientResource(uri).get(MediaType.APPLICATION_JSON);
		JSONObject object = new JSONObject(response.getText());
		if (object != null) {
			JSONArray arr = (JSONArray) object.get("data");
			logger.info("Tasklist " + actorName + " " + status + " size "	+ arr.length());
			return arr.length();
		}
		return -1;
	}
	
	public static List<String> taskQueryByActorNameBySizeAndOrder(String actorName,int size, String order, String status) throws Exception {
		List<String> taskForActor = new ArrayList<String>();
		String url = REST_URI + "/runtime/tasks?assignee="+ actorName +"&size=" + size + "&order="+order +"&status="+status;
		Representation response = getClientResource(url).get(MediaType.APPLICATION_JSON);
		if (response != null) {
			JSONObject object = new JSONObject(response.getText());
			if (object != null) {
				JSONArray arr = (JSONArray) object.get("data");
				for (int i = 0; i < arr.length(); i++) {
					JSONObject ob = (JSONObject) arr.get(i);
					taskForActor.add(ob.toString());
				}
			}
		}
		return taskForActor;
	}
}

Activiti REST Client Test

package com.nuke.activiti.client;

import static org.junit.Assert.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONException;
import org.junit.Test;

import com.nuke.activiti.common.AbstractTest;

/**
 * @author tmichels
 */
public class ActivitiClientTest extends AbstractTest {
	
	@Test
	public void testGetQueueNamesAdmin() throws IOException, JSONException {
        List<String> queueNames = NucleusClient.getQueueNames("qatester_tools");
        for (String queueName : queueNames) {
            System.out.println(queueName);
        }
        assertNotNull(queueNames);
	}
	
	
	@Test
	public void testGetQueueNames() throws JSONException, IOException {
		List<String> queueNames = NucleusClient.getQueueNames("qatester_tools");
		for (String queueName : queueNames) {
			System.out.println(queueName);
		}
		assertNotNull(queueNames);
	}
	
	@Test
	public void testGetQueueTestEdgarNames() throws JSONException, IOException {
		List<String> queueNames = NucleusClient.getQueueNames("qatester_tools");
		for (String queueName : queueNames) {
			System.out.println(queueName);
		}
		assertNotNull(queueNames);
	}
	
	@Test
	public void testNewDiagram() throws IOException, JSONException {
		assertNotNull(NucleusClient.getProcessIdByName("underwritingQueue"));
		System.out.println("OUTPUT: " + NucleusClient.getProcessIdByName("bankVerificationQueue"));
		assertNotNull(NucleusClient.getProcessIdByName("bankVerificationQueue"));
	}
	
	
	@Test
	public void testWithUserInSameLDAPGroup() throws Exception {
		assertNotNull(NucleusClient.getTaskIdByProcessIdAndActorName(NucleusClient.getProcessIdByName("underwritingQueue"), "qatester_tools"));
	}
	
	@Test
	public void testGetQueueNamesNonReturn() throws JSONException, IOException {
		List<String> queueNames = NucleusClient.getQueueNames("dummy");
		assertNull(queueNames);
	}

    @Test
    public void testLoanComplete() throws Exception {
        String underwritingQueueProcessId = NucleusClient.getProcessIdByName("underwritingQueue");
        Map<String, String> processVariables = new HashMap<String, String>();
        processVariables.put("LoanId", "1");
        String processInstanceId = NucleusClient.createTaskByProcessId(underwritingQueueProcessId, processVariables);
        assertNotNull(processInstanceId);
        assertNotNull(NucleusClient.taskQueryByActorNameBySizeAndOrder("qatester_admin", 1, "asc", "open"));
        Map<String, String> completeVariables = new HashMap<String, String>();
        completeVariables.put("disposition", "complete");
        assertTrue(NucleusClient.completeTaskByIdWithVariables("1", "qatester_tools",completeVariables));
    }

 
    @Test
    public void testLoanInComplete() throws Exception{
        String underwritingQueueProcessId = NucleusClient.getProcessIdByName("underwritingQueue");
        Map<String, String> processVariables = new HashMap<String, String>();
        processVariables.put("LoanId", "2");
        NucleusClient.createTaskByProcessId(underwritingQueueProcessId, processVariables);
        assertTrue(NucleusClient.completeTaskByIdWithVariables("2", "qatester_admin", null));
        assertNotNull(NucleusClient.taskQueryByActorNameBySizeAndOrder("qatester_admin", 1, "asc", "open"));
        Map<String, String> completeVariables = new HashMap<String, String>();
        completeVariables.put("disposition", "incomplete");
        assertTrue(NucleusClient.completeTaskByIdWithVariables("2","qatester_tools", completeVariables));
        assertNotNull(NucleusClient.taskQueryByActorNameBySizeAndOrder("qatester_admin", 1, "asc", "open"));
    }

    @Test
    public void testSaveForLater() throws Exception{
        String underwritingQueueProcessId = NucleusClient.getProcessIdByName("underwritingQueue");
        Map<String, String> processVariables = new HashMap<String, String>();
        processVariables.put("LoanId", "3");
        String processInstanceId = NucleusClient.createTaskByProcessId(underwritingQueueProcessId, processVariables);
        System.out.println(processInstanceId);
        assertTrue(NucleusClient.completeTaskByIdWithVariables("3","qatester_tools", null));
        assertNotNull(NucleusClient.taskQueryByActorNameBySizeAndOrder("qatester_admin", 1, "asc", "open"));
        Map<String, String> completeVariables = new HashMap<String, String>();
        completeVariables.put("disposition", "saveforlater");
        assertTrue(NucleusClient.completeTaskByIdWithVariables("3", "qatester_tools",completeVariables));
    }


	@Test
	public void endToEndTest() throws Exception {
		String underwritingQueueProcessId = NucleusClient.getProcessIdByName("underwritingQueue");
		assertNotNull(underwritingQueueProcessId);
		Map<String, String> processVariables = new HashMap<String, String>();
		processVariables.put("LoanId", "00000000000");
		String processInstanceId = NucleusClient.createTaskByProcessId(underwritingQueueProcessId, processVariables);
		System.out.println("processInstanceId: " + underwritingQueueProcessId);
		assertNotNull(processInstanceId);
		String taskId = NucleusClient.getTaskIdByProcessIdAndActorName(NucleusClient.getProcessIdByName("underwritingQueue"), "qatester_tools");
		assertNotNull(taskId);
		assertNotNull(NucleusClient.claimTaskByIdAndActorName(taskId, "qatester_tools"));

		assertNotNull(NucleusClient.completeTaskByIdWithVariables(taskId,"qatester_tools", null));

		assertNotNull(NucleusClient.getTaskCountByActorNameAndStatus("qatester_tools", "closed"));

        Map<String, String> completeVariables = new HashMap<String, String>();
        completeVariables.put("disposition", "saveforlater");
        NucleusClient.completeTaskByIdWithVariables(taskId,"qatester_tools", completeVariables);
        assertNotNull(NucleusClient.getTaskCountByActorNameAndStatus("qatester_tools", "closed"));
	}
	
	
	@Test
	public void testUserInSameLDAPGroup() throws Exception {
		assertNotNull(NucleusClient.getTaskIdByProcessIdAndActorName(NucleusClient.getProcessIdByName("underwritingQueue"), "qatester_tools"));
	}
	
	
	@Test
	public void testGetProcessIdByName() throws Exception {
		String queueProcessId = NucleusClient.getProcessIdByName("underwritingQueue");
		assertNotNull(queueProcessId);
	}
	
	@Test
	public void testCreateTaskByProcessId() throws Exception {
		String underwritingQueueProcessId = NucleusClient.getProcessIdByName("underwritingQueue");
		assertNotNull(underwritingQueueProcessId);
		Map<String, String> processVariables = new HashMap<String, String>();
		processVariables.put("LoanId", "332233555");
		String createComplete = NucleusClient.createTaskByProcessId(underwritingQueueProcessId, processVariables);
		System.out.println("CREATE COMPLETE: " + createComplete);
		assertNotNull(createComplete);
	}
	
	@Test
	public void testTaskByActorName() throws Exception {
		String processId = NucleusClient.getProcessIdByName("underwritingQueue");
		String taskId = NucleusClient.getTaskIdByProcessIdAndActorName(processId, "qatester_tools");
		assertNotNull(taskId);
	}
	
	@Test
	public void testClaimTaskById() throws Exception {
		String processId = NucleusClient.getProcessIdByName("underwritingQueue");
		String taskId = NucleusClient.getTaskIdByProcessIdAndActorName(processId, "qatester_tools");
		assertNotNull(NucleusClient.claimTaskByIdAndActorName(taskId, "qatester_tools"));
	}
	
	@Test
	public void testCompleteTaskById() throws Exception {
		String processId = NucleusClient.getProcessIdByName("underwritingQueue");
		Map<String, String> processVariables = new HashMap<String, String>();
		processVariables.put("LoanId", "3333333333");
		NucleusClient.createTaskByProcessId(processId, processVariables);
		String taskId = NucleusClient.getTaskIdByProcessIdAndActorName(processId, "qatester_tools");
		Map<String, String> completeVariables = new HashMap<String, String>();
		completeVariables.put("disposition", "complete");
		assertNotNull(NucleusClient.completeTaskByIdWithVariables(taskId,"qatester_tools", completeVariables));
	}
	
	@Test
	public void testIncompleteTaskById() throws Exception{
		String processId = NucleusClient.getProcessIdByName("underwritingQueue");
		Map<String, String> processVariables = new HashMap<String, String>();
		processVariables.put("LoanId", "4444444444");
		NucleusClient.createTaskByProcessId(processId, processVariables);
		String taskId = NucleusClient.getTaskIdByProcessIdAndActorName(processId, "qatester_tools");
		Map<String, String> completeVariables = new HashMap<String, String>();
		completeVariables.put("disposition", "incomplete");
		assertNotNull(NucleusClient.completeTaskByIdWithVariables(taskId,"qatester_tools", completeVariables));
	}
	
	@Test
	public void testSaveForLaterTaskById() throws Exception {
		String processId = NucleusClient.getProcessIdByName("underwritingQueue");
		Map<String, String> processVariables = new HashMap<String, String>();
		processVariables.put("LoanId", "5555555555");
		String creatProcessId = NucleusClient.createTaskByProcessId(processId, processVariables);
		System.out.println("CreatedProcessId: " + creatProcessId);
		String taskId = NucleusClient.getTaskIdByProcessIdAndActorName(processId, "qatester_tools");
		Map<String, String> completeVariables = new HashMap<String, String>();
		completeVariables.put("disposition", "saveforlater");
		assertNotNull(NucleusClient.completeTaskByIdWithVariables(taskId,"qatester_tools", completeVariables));
	}
	
	@Test
	public void testGetTaskCountByActorNameAndStatus() throws Exception {
		int taskCount = NucleusClient.getTaskCountByActorNameAndStatus("qatester_tools", "open");
		assertNotNull(taskCount);
	}
	
	@Test
	public void testTaskQueryForActorNameBySizeAndOrder() throws Exception {
		List<String> taskIds = NucleusClient.taskQueryByActorNameBySizeAndOrder("qatester_tools", 5, "asc", "open");
		for (String taskId : taskIds) {
			System.out.println("TASKID: " + taskId);
		}
		assertNotNull(taskIds);
	}
	
	@Test
	public void testGetTaskClaimAndCompleteTaskByProcessIdAndActorName() throws JSONException, IOException {
		assertNotNull(NucleusClient.claimAndCompleteTaskByProcessIdAndActorName(NucleusClient.getProcessIdByName("underwritingQueue"), "qatester_tools"));
	}

    @Test
    public void testGetTaskClaimAndCompleteTaskByProcessIdAndActorNameWithWrongActorName() throws Exception{
        assertNull(NucleusClient.claimAndCompleteTaskByProcessIdAndActorName(NucleusClient.getProcessIdByName("underwritingQueue"), "dummy"));
    }

    @Test
    public void testGetTaskClaimAndCompleteTaskByProcessIdAndActorNameWithWrongProcessName() throws Exception{
        assertNull(NucleusClient.claimAndCompleteTaskByProcessIdAndActorName(NucleusClient.getProcessIdByName("dummy"), "dummy"));
    }


    @Test
    public void testProccessIdReturnNullWhenInvalid() throws IOException, JSONException {
        assertNull(NucleusClient.getProcessIdByName("dummy"));
    }

	@Test
	public void testGetTaskByLoanId() throws JSONException, IOException {
		assertNotNull(NucleusClient.getTaskByLoanId("259190367").getJSONArray("data"));
	}
	
	@Test
	public void testSaveForlater() throws Exception {
		Map<String, String> completeVariables = new HashMap<String, String>();
		completeVariables.put("disposition", "complete");
		NucleusClient.completeTaskByIdWithVariables("685363", "qatester_tools", completeVariables);
	}
	
	@Test
	public void testSaveForLaterIfAlreadySaveForLater() throws Exception {
		String processId = NucleusClient.getProcessIdByName("underwritingQueue");
		String taskId = NucleusClient.getTaskIdByProcessIdAndActorName(processId, "qatester_tools");
		System.out.println("TaskId: " + taskId);
		Map<String, String> completeVariables = new HashMap<String, String>();
		completeVariables.put("disposition", "incomplete");
		assertNotNull(NucleusClient.completeTaskByIdWithVariables("1111111111","qatester_tools", completeVariables));
	}
}

Java REST Client with Basic Authentication

This Java Client can be used to invoke any RESTful endpoint by proving a baseURL, username and password.

import org.apache.commons.codec.binary.Base64;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

public class RESTInvoker {
    private final String baseUrl;
    private final String username;
    private final String password;

    public RESTInvoker(String baseUrl, String username, String password) {
        this.baseUrl = baseUrl;
        this.username = username;
        this.password = password;
    }

    public String getRESTResponse(String accountId){
       getDataFromServer("account/" + accountId);
    }

    String getDataFromServer(String path) {
        StringBuilder sb = new StringBuilder();
        try {
            URL url = new URL(baseUrl + path);
            URLConnection urlConnection = setUsernamePassword(url);
            BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();

            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private URLConnection setUsernamePassword(URL url) throws IOException {
        URLConnection urlConnection = url.openConnection();
        String authString = username + ":" + password;
        String authStringEnc = new String(Base64.encodeBase64(authString.getBytes()));
        urlConnection.setRequestProperty("Authorization", "Basic " + authStringEnc);
        return urlConnection;
    }
}

My Dreamforce 2013 Developer Theater Presentation

Exposing Force.com RESTful Services using Swagger.

Try it live:
http://force-com-rest-swagger.herokuapp.com

Fork my project
https://github.com/thysmichels/force.com-swagger-rest-spring-mvc

Here are some photos from the event:

photo 1

photo 2

Presentation attached:
DF13_Exposing Salesforce REST Service using Swagger

Youtube video:

Apigee as Force.com REST provider

Apigee has an extensive Force.com REST interface to interact with Salesforce. Follow this tutorial to create an app in apigee, create a remote connection in Salesforce, add a user to the app to get your smart-key.

Complete the tutorial below to get the information needed to run this class:

http://developer.apigee.com/salesforce_tutorial.html

You will need the following to run this class:
1. Smart-key
2. Application Name

import com.apigee.sdk.oauth.api.exception.RestCallException;
import com.apigee.sdk.oauth.api.rest.RestCallResult;
import com.apigee.sdk.oauth.api.rest.RestCall;
import com.apigee.sdk.oauth.impl.model.Request;

public class ForceApigee {

	   //Configure your SMARTKEY and APPNAME
	   final static String SMARTKEY = "YOURSMARTKEY";
	   final static String APPNAME = "YOURAPPLICATIONNAME";
	   final static String PROVIDER = "salesforce";
	   
	   final static String VERSIONENDPOINT = "/services/data";
	   final static String RESOURCESENDPOINT = "/services/data/v27.0";
	   final static String SOBJECTENDPOINT = "/services/data/v27.0/sobjects";
	   final static String SOBJECTBASICENDPOINT = "/services/data/v24.0/sobjects/Account";
	   final static String SOBJECTDESCRIBEENDPOINT = "/services/data/v27.0/sobjects/Account/describe";
	   final static String SOQLQUERYENDPOINT = "/services/data/v24.0/query?q=SELECT name from Account";
	   final static String SOQLSEARCHENDPOINT = "/services/data/v24.0/search?q=FIND {test} IN ALL FIELDS";
	
	   public static String callToSalesforce(Request.HttpVerb verb, String Endpoint)
	   {
		   try 
		   {
	           RestCallResult result = new RestCall(verb, Endpoint)
	             .withSmartKey(SMARTKEY)
	             .toProvider(PROVIDER)
	             .usingApp(APPNAME)
	             .invoke();
				 return result.getResponsePayload().toString();
	       } catch (RestCallException e) {
			   return e.getMessage();
	       }
	   } 
	   
	   public static void main(String[] args)
	   {
	   		System.out.println("***VERSIONENDPOINT****: \n" + callToSalesforce(Request.HttpVerb.GET, VERSIONENDPOINT));
	   		System.out.println("***RESOURCESENDPOINT***: \n" + callToSalesforce(Request.HttpVerb.GET, RESOURCESENDPOINT));
	   		System.out.println("***SOBJECTENDPOINT***: \n" + callToSalesforce(Request.HttpVerb.GET, SOBJECTENDPOINT));
	   		System.out.println("***SOBJECTBASICENDPOINT***: \n" + callToSalesforce(Request.HttpVerb.GET, SOBJECTBASICENDPOINT));
	   		System.out.println("***SOBJECTDESCRIBEENDPOINT***: \n" + callToSalesforce(Request.HttpVerb.GET, SOBJECTDESCRIBEENDPOINT));
	   		System.out.println("***SOQLQUERYENDPOINT***: \n" + callToSalesforce(Request.HttpVerb.GET, SOQLQUERYENDPOINT));
	   		System.out.println("***SOQLSEARCHENDPOINT***: \n" + callToSalesforce(Request.HttpVerb.GET, SOQLSEARCHENDPOINT));
	   }
}

Force.com REST Swagger Spring MVC

Swagger is a specification and complete framework implementation for describing, producing, consuming, and visualizing RESTful web services. The overarching goal of Swagger is to enable client and documentation systems to update at the same pace as the server. The documentation of methods, parameters, and models are tightly integrated into the server code, allowing APIs to always stay in sync. With Swagger, deploying managing, and using powerful APIs has never been easier.

Spring Swagger Controller code

package com.thysmichels.swagger4forcedotcom.controllers;

import com.knappsack.swagger4springweb.controller.ApiDocumentationController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * This is an example of how you might extend the ApiDocumentationController in order to set your own RequestMapping
 * (instead of the default "/api") among other possibilities.  Going this route, you do not necessarily have to define
 * the controller in your servlet context.
 */
@Controller
@RequestMapping(value = "/api")
public class ExampleDocumentationController extends ApiDocumentationController {

    public ExampleDocumentationController() {
        setBaseControllerPackage("com.thysmichels.swagger4forcedotcom.controllers.api");
        setBaseModelPackage("com.thysmichels.swagger4forcedotcom.models");
        setApiVersion("v1");
    }

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String documentation() {
        return "api";
    }
}

Force.com REST Implementation Code

package com.thysmichels.swagger4forcedotcom.controllers.api;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.ws.rs.core.Response;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;


import com.force.api.ForceApi;
import com.force.api.QueryResult;
import com.thysmichels.swagger4forcedotcom.models.Account;
import com.thysmichels.swagger4forcedotcom.services.SalesforceLogin;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiError;
import com.wordnik.swagger.annotations.ApiErrors;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;

@Controller
@RequestMapping(value = "/api/v1/account")
@Api(value = "Account operations", listingClass = "AccountController", basePath = "/api/v1/account", description = "All operations for accounts")
public class AccountController {
	
	@Inject
	@Named("SalesforceLogin")
	private SalesforceLogin sfdcLogin;
	private ForceApi api;
	
	@PostConstruct
	public void init()
	{
		api = sfdcLogin.loginToSalesforce();
	}
	
	 @ApiOperation(value = "Find all accounts", notes = "Get all account currently available", httpMethod = "GET", responseClass = "Account", multiValueResponse = true)
	 @ApiError(code = 500, reason = "Process error")
	 @RequestMapping(value = "/", method = RequestMethod.GET, produces = "application/json")
	 public @ResponseBody List<Account> showAllAccounts() {
	    	QueryResult<Account> res = api.query("SELECT Name FROM Account", Account.class);
	        return res.getRecords();
	 }
	
	@ApiOperation(value = "Find account by Id", notes = "Get account by specifying Id", httpMethod = "GET", responseClass = "Account", multiValueResponse = true)
	@ApiErrors(value = { @ApiError(code = 400, reason = "Invalid ID supplied"), @ApiError(code = 404, reason = "Account not found") })
	@RequestMapping(value = "/{accountId}", method = RequestMethod.GET, produces = "application/json")
    public @ResponseBody Account[] findAccountById(@ApiParam(internalDescription = "java.lang.string", name = "accountId", required = true, value = "string") @PathVariable String accountId) {
    	Account account = api.getSObject("account", accountId).as(Account.class);
        return new Account[]{account};
    }

	
	@ApiOperation(value = "Delete a account", notes = "Delete a specific account with the given ID", httpMethod = "DELETE")
    @ApiError(code = 500, reason = "Process error")
    @RequestMapping(value = "/{accountId}", method = RequestMethod.DELETE, produces = "application/json")
    public @ResponseBody String deleteAccount(@ApiParam(internalDescription = "java.lang.string", name = "accountId", required = true, value = "string") @PathVariable String accountId) {
    	api.deleteSObject("account", accountId);
    	return "{status: success}";
    }
	
	@ApiOperation(value = "Create a account using Param", notes = "Creates a new account in salesforce using Param", httpMethod = "POST")
    @ApiError(code = 500, reason = "Process error")
    @RequestMapping(method = RequestMethod.POST, produces = "application/json")
    public @ResponseBody String createAccountFromParamName(@ApiParam(internalDescription = "java.lang.string", value="string", name = "Name", required = false) @RequestParam(required = true) String Name) 
    {	
		Account newAccount = new Account();
		newAccount.setName(Name);
    	String id = api.createSObject("Account", newAccount);
    	return "{id:" + id +"}";
    }
	
	@ApiOperation(value = "Create a account", notes = "Creates a new account in salesforce", httpMethod = "POST")
    @ApiError(code = 500, reason = "Process error")
    @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
    public @ResponseBody String createAccountFromJSON(@RequestBody Account newAccount) 
    {	
    	String id = api.createSObject("Account", newAccount);
    	return "{id:" + id +"}";
    }
	
	@ApiOperation(value = "Update Account", notes = "Update a existing Account", httpMethod = "POST") 
	@RequestMapping(value = "/{accountId}", method = RequestMethod.POST, consumes = "application/json")
	 public @ResponseBody String updateAccount(@PathVariable String accountId, @RequestBody Account account) {
		 api.updateSObject("Account", accountId, account);
		 return "{status: success}";
	 }
}

Screenshots

Salesforce Spring MVC Swagger

Salesforce Spring MVC Swagger1

CloudSole Salesforce REST Feed

I was looking at building a easy way to POST information from your salesforce org to my Public Feed. This feed can be used to publish and data from you salesforce org to the public.

Below is some code sameples on ways to POST to the Public Feed:

curl:

curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"name": "I love Cloudsole Salesforce Feed", "message": "This is awesome I can post my message on the public feed"}' http://cloudsole-feed.herokuapp.com/sfdc/public/feed

Apex code:

Note:

Make sure to add http://cloudsole-feed.herokuapp.com to you Remote Site Details.

Code:

public with sharing class HttpCalloutToFeed 
{
  public static void sentMessageToFeed()
  { 
    Http http = new Http();
    HttpRequest httpreq = new HttpRequest(); 
    httpreq.setEndpoint('http://cloudsole-feed.herokuapp.com/sfdc/public/feed'); 
    String message = '{"name": "Message from ' + UserInfo.getFirstName() + '", "message": "My Organization ' + UserInfo.getOrganizationName() + ' located in ' + UserInfo.getLocale() + ' loves CloudSole public feed"}';
    httpreq.setHeader('Accept', 'application/json');
    httpreq.setHeader('Content-type', 'application/json');
    httpreq.setBody(message);
    httpreq.setMethod('POST');
    HttpResponse response = http.send(httpreq); 
    System.debug(response.getBody());
  } 
}

Java code:

package com.thysmichels.main;

import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;

public class CloudSoleFeedMain 
{
    public static void main(String[] args) 
    {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost("http://cloudsole-feed.herokuapp.com/sfdc/public/feed");

        try 
        {
            post.setEntity(new StringEntity("{\"name\": \"Message from Java Class\", \"message\": \"This is awesome I can post my message on the public feed\"}"));
            post.setHeader("Accept", "application/json");
            post.setHeader("Content-Type", "application/json");
            HttpResponse response = client.execute(post);
        } catch (IOException e) {
        e.printStackTrace();
        }
    }
}

https://github.com/thysmichels/cloudsole_hibernate_rest_salesforce_feed