diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/model.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/model.get.desc.xml
new file mode 100644
index 0000000000..3435509ac5
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/model.get.desc.xml
@@ -0,0 +1,12 @@
+
+ Get Model
+ Get the model for given model name.
+ /api/solr/model/{modelShortQName}
+ argument
+ admin
+ required
+ internal
+ SOLR
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/modelsdiff.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/modelsdiff.post.desc.xml
new file mode 100644
index 0000000000..3072288fba
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/modelsdiff.post.desc.xml
@@ -0,0 +1,12 @@
+
+ Get Model Diffs
+ Get a diff of models given parameters passed in.
+ /api/solr/modelsdiff
+ argument
+ admin
+ required
+ internal
+ SOLR
+
+
+
\ No newline at end of file
diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/solr/modelsdiff.post.json.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/modelsdiff.post.json.ftl
new file mode 100644
index 0000000000..e153dc99cd
--- /dev/null
+++ b/config/alfresco/templates/webscripts/org/alfresco/repository/solr/modelsdiff.post.json.ftl
@@ -0,0 +1,14 @@
+<#import "solr.lib.ftl" as solrLib/>
+{
+ "diffs" :
+ [
+ <#list diffs as diff>
+ {
+ "name": <@solrLib.qNameJSON qName=diff.modelName/>,
+ "type" : "${diff.type}",
+ "oldChecksum": <#if diff.oldChecksum??>${diff.oldChecksum?c}<#else>null#if>,
+ "newChecksum": <#if diff.newChecksum??>${diff.newChecksum?c}<#else>null#if>
+ }<#if diff_has_next>,#if>
+ #list>
+ ]
+}
\ No newline at end of file
diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml
index a3111c12b3..b1cdf4effb 100644
--- a/config/alfresco/web-scripts-application-context.xml
+++ b/config/alfresco/web-scripts-application-context.xml
@@ -1355,6 +1355,19 @@
+
+
+
+
+
+
+
+
+
diff --git a/source/java/org/alfresco/repo/web/scripts/solr/AlfrescoModelGet.java b/source/java/org/alfresco/repo/web/scripts/solr/AlfrescoModelGet.java
new file mode 100644
index 0000000000..d39ee7510b
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/solr/AlfrescoModelGet.java
@@ -0,0 +1,76 @@
+package org.alfresco.repo.web.scripts.solr;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.alfresco.repo.solr.AlfrescoModel;
+import org.alfresco.repo.solr.SOLRTrackingComponent;
+import org.alfresco.service.cmr.dictionary.ModelDefinition;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONException;
+import org.springframework.extensions.webscripts.AbstractWebScript;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptException;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+import org.springframework.extensions.webscripts.WebScriptResponse;
+
+/**
+ * Support for SOLR: Get Alfresco model
+ *
+ * @since 4.0
+ */
+public class AlfrescoModelGet extends AbstractWebScript
+{
+ protected static final Log logger = LogFactory.getLog(AlfrescoModelGet.class);
+
+ private NamespaceService namespaceService;
+ private SOLRTrackingComponent solrTrackingComponent;
+
+ public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
+ {
+ this.solrTrackingComponent = solrTrackingComponent;
+ }
+
+ public void setNamespaceService(NamespaceService namespaceService)
+ {
+ this.namespaceService = namespaceService;
+ }
+
+ public void execute(WebScriptRequest req, WebScriptResponse res)
+ {
+ try
+ {
+ handle(req, res);
+ }
+ catch(IOException e)
+ {
+ throw new WebScriptException("IO exception parsing request", e);
+ }
+ catch(JSONException e)
+ {
+ throw new WebScriptException("Invalid JSON", e);
+ }
+ }
+
+ private void handle(WebScriptRequest req, WebScriptResponse res) throws JSONException, IOException
+ {
+ // create map of template vars
+ Map templateVars = req.getServiceMatch().getTemplateVars();
+ String modelName = templateVars.get("modelShortQName");
+ if(modelName == null)
+ {
+ throw new WebScriptException(
+ Status.STATUS_BAD_REQUEST,
+ "URL parameter 'modelShortQName' not provided.");
+ }
+
+ ModelDefinition.XMLBindingType bindingType = ModelDefinition.XMLBindingType.SOLR;
+ AlfrescoModel model = solrTrackingComponent.getModel(QName.createQName(modelName, namespaceService));
+ res.setHeader("XAlfresco-modelChecksum", String.valueOf(model.getModelDef().getChecksum(bindingType)));
+ model.getModelDef().toXML(bindingType, res.getOutputStream());
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/web/scripts/solr/AlfrescoModelsDiff.java b/source/java/org/alfresco/repo/web/scripts/solr/AlfrescoModelsDiff.java
new file mode 100644
index 0000000000..1ac3afa168
--- /dev/null
+++ b/source/java/org/alfresco/repo/web/scripts/solr/AlfrescoModelsDiff.java
@@ -0,0 +1,87 @@
+package org.alfresco.repo.web.scripts.solr;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.alfresco.repo.solr.AlfrescoModelDiff;
+import org.alfresco.repo.solr.SOLRTrackingComponent;
+import org.alfresco.service.namespace.QName;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.springframework.extensions.surf.util.Content;
+import org.springframework.extensions.webscripts.DeclarativeWebScript;
+import org.springframework.extensions.webscripts.Status;
+import org.springframework.extensions.webscripts.WebScriptException;
+import org.springframework.extensions.webscripts.WebScriptRequest;
+
+/**
+ * Support for SOLR: Track Alfresco model changes
+ *
+ * @since 4.0
+ */
+public class AlfrescoModelsDiff extends DeclarativeWebScript
+{
+ protected static final Log logger = LogFactory.getLog(AlfrescoModelsDiff.class);
+
+ private SOLRTrackingComponent solrTrackingComponent;
+
+ public void setSolrTrackingComponent(SOLRTrackingComponent solrTrackingComponent)
+ {
+ this.solrTrackingComponent = solrTrackingComponent;
+ }
+
+ protected Map executeImpl(WebScriptRequest req, Status status)
+ {
+ try
+ {
+ Map model = buildModel(req);
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
+ }
+ return model;
+ }
+ catch(IOException e)
+ {
+ throw new WebScriptException("IO exception parsing request", e);
+ }
+ catch(JSONException e)
+ {
+ throw new WebScriptException("Invalid JSON", e);
+ }
+ }
+
+ private Map buildModel(WebScriptRequest req) throws JSONException, IOException
+ {
+ Map model = new HashMap(1, 1.0f);
+
+ Content content = req.getContent();
+ if(content == null)
+ {
+ throw new WebScriptException("Failed to convert request to String");
+ }
+ JSONObject o = new JSONObject(content.getContent());
+ JSONArray jsonModels = o.getJSONArray("models");
+ Map models = new HashMap(jsonModels.length());
+ for(int i = 0; i < jsonModels.length(); i++)
+ {
+ JSONObject jsonModel = jsonModels.getJSONObject(i);
+ models.put(QName.createQName(jsonModel.getString("name")), jsonModel.getLong("checksum"));
+ }
+
+ List diffs = solrTrackingComponent.getModelDiffs(models);
+ model.put("diffs", diffs);
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Result: \n\tRequest: " + req + "\n\tModel: " + model);
+ }
+
+ return model;
+ }
+}