Hello, thank you for your quick response.
I have not managed to implement the solution that you provide in my code. I am going to pass my Java class with the @POST service and the Java class that calls the module that implements the writing logic in the repository (and where I need to create the valid session for writing in JCR)
POST SERVICE:
package com.santander.rest.migration;
import com.google.gson.Gson;
import com.santander.rest.migration.models.ApiContainerPayloadMigration;
import com.santander.rest.migration.modules.MigrationContentModule;
import com.santander.utils.Constants;
import io.swagger.annotations.Api;
import kafka.api.Request;
import org.hippoecm.hst.container.RequestContextProvider;
import org.hippoecm.hst.core.component.HstRequest;
import org.hippoecm.hst.core.component.HstResponse;
import org.hippoecm.hst.core.request.HstRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.RepositoryException;
import javax.servlet.http.HttpServlet;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Objects;
@Api(value = "Migration content")
public class ContentMigrationService extends HttpServlet {
private static Logger logger = LoggerFactory.getLogger(ContentMigrationService.class);
private static Gson gson = new Gson();
@POST
@Path("/import/documents")
@Produces(MediaType.APPLICATION_JSON)
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
public Response getMigrationContent(@FormParam("payload") String payload, @FormParam("type") String type) throws RepositoryException {
logger.info("entering migration rest service {} {}",payload,type);
MigrationContentModule migrationContent = new MigrationContentModule();
HstRequestContext requestContext = RequestContextProvider.get();
HstRequest request = RequestContextProvider.get();
HstResponse response;
try {
if (Objects.nonNull(payload) || Objects.nonNull(type)) {
logger.info("*****/Invokong method getMigration by POST to get payload: {}", payload);
logger.info("*****/Invokong method getMigration by POST to get type: {}", type);
//COMPROBAMOS EL TIPO PARA PARSEAR PAYLOAD
if(type.contains(Constants.DOC_TYPE_API_CONTAINER_ITEM)){
ApiContainerPayloadMigration apiContainerPayload = gson.fromJson(payload, ApiContainerPayloadMigration.class);
logger.info("API Container created Payload successfully ");
migrationContent.createOrUpdateApiContainer(apiContainerPayload, requestContext);
}else{
//ES OTRO TIPO
}
return Response.status(201).entity("ok response").build();
} else {
logger.info("*****/Invokong method getMigration by POST to get payload: {}", payload);
logger.info("*****/Invokong method getMigration by POST to get type: {}", type);
return Response.status(201).entity("params empty").build();
}
}catch (Exception e){
logger.error("*****/Invokong method getMigration error", e);
}
return Response.status(201).entity("ok response").build();
}
}
MIGRATION MODULE:
package com.santander.rest.migration.modules;
import com.santander.rest.migration.MigrationContentException;
import com.santander.rest.migration.models.ApiContainerPayloadMigration;
import com.santander.utils.Constants;
import org.apache.commons.lang3.RegExUtils;
import org.hippoecm.hst.component.support.bean.BaseHstComponent;
import org.hippoecm.hst.core.request.HstRequestContext;
import org.hippoecm.repository.api.Document;
import org.hippoecm.repository.api.HippoWorkspace;
import org.hippoecm.repository.api.MappingException;
import org.hippoecm.repository.api.WorkflowException;
import org.hippoecm.repository.standardworkflow.FolderWorkflow;
import org.hippoecm.repository.util.MavenComparableVersion;
import org.onehippo.forge.content.exim.core.impl.WorkflowDocumentManagerImpl;
import org.onehippo.forge.content.exim.core.impl.WorkflowDocumentVariantImportTask;
import org.onehippo.forge.content.pojo.model.ContentNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.*;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.Locale;
public class MigrationContentModule extends BaseHstComponent {
private static final Logger LOGGER = LoggerFactory.getLogger(MigrationContentModule.class);
private static Session session;
public void createOrUpdateApiContainer(ApiContainerPayloadMigration apiContainerPayload, HstRequestContext requestContext) throws MigrationContentException {
LOGGER.info("*****/Invokong method createOrUpdateApiContainer -->PATH of ApiContainerPayload {}", apiContainerPayload.getPath());
String pathApiContainer = apiContainerPayload.getPath();
Session threadSafeSession = null;
try {
//FORMA 1 session
//For thread safety
threadSafeSession = requestContext.getSession().impersonate(new SimpleCredentials("admin", "admin".toCharArray()));
//FORMA 2 session
//HippoRepository repository = HippoRepositoryFactory.getHippoRepository("vm://");
//threadSafeSession = repository.login("admin", "admin".toCharArray());
// threadSafeSession = UserSession.get().getJcrSession();
/*
final HttpServletRequest request = requestContext.getServletRequest();
User user = (User) request.getSession().getAttribute("user");
if (user == null) {
try {
final Session userSession = requestContext.getSession();
//session.impersonate(new SimpleCredentials(session.getUserID(), new char[0]));
user = userSession.getUserID();
request.getSession().setAttribute("user", user);
threadSafeSession = (Session) request.getSession();
} catch (RepositoryException e) {
LOGGER.error("Failed to retrieve user from repository", e);
}
}
if (user != null) {
request.setAttribute("user", user);
}*/
Node nodeApiContainer = requestContext.getSession().getNode(pathApiContainer);
//Step 1. Find out if we have to
// 1) Create a brand new instance: If There are no existing items
// 2) Modify an existing instance: If Exists a apiContainer with the same name and id
// 3) Clone an existing instance: If The new apiContainer is of an existing type and a superior version
// 4) Error: Create a new API of a non existant version.
Node updateNode = null;
Node nodeToCopy = null;
HashMap<String,Object> nodeParams = new HashMap<String,Object>();
nodeToCopy = findCopyAndExtractInfo(apiContainerPayload, nodeApiContainer, updateNode, nodeToCopy, nodeParams);
//Step 2. we do this step to obtain the producer organization or document which are used
//to get the path to the node
// that will we update or create
Document document = null;
Node producerOrganization = null;
document = processNodeToCopy(apiContainerPayload, threadSafeSession, nodeToCopy, nodeParams, document);
//get the producer organization to check its name
producerOrganization = setProducerOrganization(apiContainerPayload.getProducerOrganizationContainer(), threadSafeSession,null);
WorkflowDocumentManagerImpl documentManager;
WorkflowDocumentVariantImportTask importTask;
documentManager = new WorkflowDocumentManagerImpl(threadSafeSession);
importTask = new WorkflowDocumentVariantImportTask(documentManager);
//CREATE APICONTAINER
String newApiContainerPath = createApiContainer(apiContainerPayload, threadSafeSession, document, producerOrganization, importTask);
LOGGER.info("newApiContainerPath {}",newApiContainerPath );
Node newApiContainerNode = threadSafeSession.getNode(newApiContainerPath);
for (NodeIterator nodeIterator = newApiContainerNode.getNodes(); nodeIterator.hasNext(); )
{
Node node = nodeIterator.nextNode();
}
linkProducerOrgToApiContainer(producerOrganization, newApiContainerPath, threadSafeSession);
LOGGER.info("Description to copy from old version {}",nodeParams.get(Constants.OLD_DESCRIPTION));
setOldDescription(threadSafeSession, nodeParams, newApiContainerPath);
setOldIcon(threadSafeSession, (Value)nodeParams.get(Constants.OLD_ICON), (Value[])nodeParams.get(Constants.OLD_ICON_VALUES)
, (Value[])nodeParams.get(Constants.OLD_ICON_MODES), (Value[])nodeParams.get(Constants.OLD_ICON_FACETS)
, newApiContainerPath);
//ESTO PUBLICA NO ES NECESRIO POR AHORA
/*final HippoWorkspace workspace = (HippoWorkspace) threadSafeSession.getWorkspace();
final WorkflowManager workflowManager = workspace.getWorkflowManager();
final Node folder = session.getNode(StringUtils.substringBefore(newApiContainerPath,
APICONTAINERS)
+ APICONTAINERS);
Node documentNode = folder.getNode(RegExUtils.replaceAll(apiContainerPayload.getName()
,PATTERN_SPACES, PATTERN_SCORE).toLowerCase(Locale.UK)
+ "." + apiContainerPayload.getVersion().toLowerCase(Locale.UK));
final DocumentWorkflow documentWorkflow = (DocumentWorkflow) workflowManager
.getWorkflow(DEFAULT, document == null ? documentNode : document.getNode(threadSafeSession));
if (documentWorkflow.hints().get(PUBLISH).equals(true)) {
documentWorkflow.publish();
}*/
} catch (Exception e) {
LOGGER.error("",e);
throw new MigrationContentException("Error "+e.getMessage());
}
}
private void setOldIcon(Session threadSafeSession, Value oldIcon, Value[] oldIconValues, Value[] oldIconModes, Value[] oldIconFacets, String newApiPath) throws RepositoryException {
if (oldIcon!=null)
{
setIconToApiContainer(oldIcon, oldIconValues, oldIconModes, oldIconFacets, newApiPath, threadSafeSession);
}
}
private void setIconToApiContainer(Value icon, Value[] iconValues,Value[] iconModes,Value[] iconFacets ,String newApiContainerPath, Session session) throws RepositoryException {
LOGGER.info("Setting icon to api container");
Node newApiContainerNode = session.getNode(newApiContainerPath);
for (NodeIterator apiContainerIterator = newApiContainerNode.getNodes(); apiContainerIterator.hasNext(); ) {
Node apiContainerVariant = apiContainerIterator.nextNode();
Node descriptionNode = apiContainerVariant.addNode(Constants.SANTANDERBRXM_ICON,
"hippogallerypicker:imagelink");
descriptionNode.setProperty(Constants.HIPPO_DOCBASE, icon);
descriptionNode.setProperty(Constants.HIPPO_VALUES, iconValues);
descriptionNode.setProperty(Constants.HIPPO_MODES, iconModes);
descriptionNode.setProperty(Constants.HIPPO_FACETS, iconFacets);
session.save();
}
}
private void setOldDescription(Session session, HashMap<String, Object> nodeParams, String newApiContainerPath) throws RepositoryException {
if (nodeParams.get(Constants.OLD_DESCRIPTION)!=null)
{
setEnrichedTextToApiItem((String)nodeParams.get(Constants.OLD_DESCRIPTION),Constants.SANTANDERBRXM_DESCRIPTION,newApiContainerPath, session);
}
}
private void setEnrichedTextToApiItem(String message, String nodeName , String newNodePath, Session session) throws RepositoryException {
LOGGER.info("Setting desctiption to api item");
Node newApiItemNode = session.getNode(newNodePath);
for (NodeIterator apiContainerIterator = newApiItemNode.getNodes(); apiContainerIterator.hasNext(); ) {
Node apiContainerVariant = apiContainerIterator.nextNode();
Node descriptionNode = apiContainerVariant.addNode(nodeName, "hippostd:html");
descriptionNode.setProperty(Constants.HIPPO_CONTENT, message);
session.save();
}
}
private void linkProducerOrgToApiContainer(Node producerOrganization, String newApiContainerPath, Session session) throws RepositoryException {
LOGGER.info("linking producer organization to api container");
Node newApiContainerNode = session.getNode(newApiContainerPath);
for (NodeIterator apiContainerIterator = newApiContainerNode.getNodes(); apiContainerIterator.hasNext(); ) {
Node apiContainerVariant = apiContainerIterator.nextNode();
Node producerOrg = apiContainerVariant.addNode("santanderbrxm:producerOrganizationContainer",
Constants.HIPPO_MIRROR);
producerOrg.setProperty(Constants.HIPPO_DOCBASE, producerOrganization.getIdentifier());
session.save();
}
}
private String createApiContainer(ApiContainerPayloadMigration apiContainerPayload, Session session, Document document, Node producerOrganization, WorkflowDocumentVariantImportTask importTask) throws RepositoryException, MigrationContentException {
String newApiContainerPath = "";
ContentNode contentNodeApiContainer = new ContentNode(apiContainerPayload.getName(), Constants.DOC_TYPE_API_CONTAINER_ITEM);
contentNodeApiContainer.setProperty(Constants.SANTANDERBRXM_VERSION_IL, apiContainerPayload.getVersion());
contentNodeApiContainer.setProperty(Constants.SANTANDERBRXM_STATUS, apiContainerPayload.getStatus());
contentNodeApiContainer.setProperty(Constants.SANTANDERBRXM_PROD_ORGANIZATION_CONTAINER, apiContainerPayload.getProducerOrganizationContainer());
contentNodeApiContainer.setProperty(Constants.SANTANDERBRXM_EXPOSURE, apiContainerPayload.getExposure());
//contentNodeApiContainer.setProperty(Constants.SANTANDERBRXM_DESCRIPTION, apiContainerPayload.getDescription());
//contentNodeApiContainer.setProperty(Constants.SANTANDERBRXM_ICON, apiContainerPayload.getIcon());
//contentNodeApiContainer.setProperty(Constants.SANTANDERBRXM_PK, apiContainerPayload.getName() + "_" + apiContainerPayload.getVersion() + "_" + apiContainerPayload.getContainerProducerOrg());
checkProducerOrg(apiContainerPayload, producerOrganization);
newApiContainerPath = importTask.createOrUpdateDocumentFromVariantContentNode(contentNodeApiContainer, Constants.DOC_TYPE_API_CONTAINER_ITEM,
document != null ? document.getNode(session).getPath() :
(Constants.PRODUCER_ORGANIZATIONS_FOLDER + producerOrganization.getName() +
Constants.APICONTAINERS + RegExUtils
.replaceAll(apiContainerPayload.getName(),Constants.PATTERN_SPACES,Constants.PATTERN_SCORE)
.toLowerCase(Locale.UK) + "." + apiContainerPayload.getVersion().toLowerCase(Locale.UK)),
Constants.EN_GB, apiContainerPayload.getName());
return newApiContainerPath;
}
private static void checkProducerOrg(ApiContainerPayloadMigration apiContainerPayload, Node producerOrganization)throws MigrationContentException {
LOGGER.info("producerOrganization {}",producerOrganization);
if (producerOrganization==null)
{
throw new MigrationContentException
("Producer Org not found: "+ apiContainerPayload.getProducerOrganizationContainer());
}
}
private static Node findCopyAndExtractInfo(ApiContainerPayloadMigration apiContainerPayload, Node nodeApiContainer, Node updateNode, Node nodeToCopy, HashMap<String, Object> nodeParams) throws RepositoryException, MigrationContentException {
if (nodeApiContainer != null && nodeApiContainer.getNodes().hasNext()) {
Node copyCandidate = null;
for (NodeIterator nodeIterator = nodeApiContainer.getNodes(); nodeIterator.hasNext(); ) {
Node node = nodeIterator.nextNode();
if (copyCandidate == null) {
//get the path of the handle node of the document to copy
copyCandidate = node;
} else {
MavenComparableVersion nodeILVersion = new MavenComparableVersion(node.getProperty(Constants.SANTANDERBRXM_VERSION_IL).getString());
MavenComparableVersion nodeCandidateVersion = new MavenComparableVersion(copyCandidate.getProperty(Constants.SANTANDERBRXM_VERSION_IL).getString());
MavenComparableVersion newVersion = new MavenComparableVersion(apiContainerPayload.getVersion());
if (nodeILVersion.compareTo(nodeCandidateVersion) > 0) {
copyCandidate = node;
} else if (nodeILVersion.compareTo(newVersion) == 0) {
updateNode = node;
Node nodeDescription = null;
extractNodeDescription(updateNode, nodeParams, nodeDescription);
extractApiNodeIcon(updateNode, nodeParams);
LOGGER.info("Escenario 2. existing node with same id and version. it will be updated");
break;
} else {
//Do nothing
}
}
}
//there is no equal version, we clone if copy Candidate is superior to the existing one, otherwise,
nodeToCopy = cloneCopyCandidate(apiContainerPayload, updateNode, nodeToCopy, copyCandidate);
} else {
LOGGER.info("Escenario 1. There are no previous versions, a new one will be created.");
}
return nodeToCopy;
}
public static Node cloneCopyCandidate(ApiContainerPayloadMigration apiContainerPayload, Node updateNode, Node nodeToCopy, Node copyCandidate) throws ValueFormatException, RepositoryException, PathNotFoundException, MigrationContentException {
if (updateNode==null)
{
MavenComparableVersion newVersion = new MavenComparableVersion(apiContainerPayload.getVersion());
MavenComparableVersion nodeCandidateVersion = new MavenComparableVersion(copyCandidate
.getProperty(Constants.SANTANDERBRXM_VERSION_IL).getString());
int comparation = newVersion.compareTo(nodeCandidateVersion);
if (comparation > 0)
{
nodeToCopy = copyCandidate;
LOGGER.info("Escenario 3. node to copy: {} version {}", nodeToCopy.getName()
,nodeToCopy.getProperty(Constants.SANTANDERBRXM_VERSION_IL).getString());
}
else
{
throw new MigrationContentException("Escenario 4. can't create apiContainer because newVersion "
+ apiContainerPayload.getVersion() + "is inferior to current version "
+ copyCandidate.getProperty(Constants.SANTANDERBRXM_VERSION_IL).getString() );
}
}
return nodeToCopy;
}
private static void extractNodeDescription(Node updateNode, HashMap<String, Object> nodeParams, Node nodeDescription) throws PathNotFoundException, RepositoryException, ValueFormatException {
nodeDescription = extractNodeDescriptionApi(updateNode, nodeDescription);
if (nodeDescription!=null && nodeDescription.getProperty(Constants.HIPPO_CONTENT)!=null)
{
nodeParams.put(Constants.OLD_DESCRIPTION,nodeDescription.getProperty(Constants.HIPPO_CONTENT)
.getString());
}
}
private static void extractApiNodeIcon(Node updateNode, HashMap<String, Object> nodeParams)throws PathNotFoundException, RepositoryException, ValueFormatException {
Node nodeIcon=null;
nodeIcon = extractNodeIcon(updateNode, nodeIcon);
if (nodeIcon!=null && nodeIcon.getProperty(Constants.HIPPO_DOCBASE)!=null
&& nodeIcon.getProperty(Constants.HIPPO_VALUES)!=null)
{
nodeParams.put(Constants.OLD_ICON,nodeIcon.getProperty(Constants.HIPPO_DOCBASE).getValue());
nodeParams.put(Constants.OLD_ICON_VALUES,nodeIcon.getProperty(Constants.HIPPO_VALUES).getValues());
nodeParams.put(Constants.OLD_ICON_MODES,nodeIcon.getProperty(Constants.HIPPO_MODES).getValues());
nodeParams.put(Constants.OLD_ICON_FACETS,nodeIcon.getProperty(Constants.HIPPO_FACETS).getValues());
}
}
public static Node extractNodeDescriptionApi(Node updateNode, Node nodeDescription) {
try
{
nodeDescription=updateNode.getNode(Constants.SANTANDERBRXM_DESCRIPTION);
} catch (RepositoryException e)
{
LOGGER.info("no description {}",e.getMessage());
}
return nodeDescription;
}
public static Node extractNodeIcon(Node updateNode, Node nodeIcon) {
try
{
nodeIcon=updateNode.getNode(Constants.SANTANDERBRXM_ICON);
} catch (RepositoryException e)
{
LOGGER.info("no node icon {}",e.getMessage());
}
return nodeIcon;
}
private static Document processNodeToCopy(ApiContainerPayloadMigration apiContainerPayload, Session session, Node nodeToCopy, HashMap<String, Object> nodeParams, Document document) throws MappingException,RepositoryException, ItemNotFoundException, AccessDeniedException, WorkflowException, RemoteException {
if (nodeToCopy != null) {
//WorkflowManager wflManager = (WorkflowManager) ((HippoWorkspace) session.getWorkspace()).getWorkflowManager().getWorkflow("threepane", nodeToCopy.getParent().getParent());
//Workflow workflow = wflManager.getWorkflow("threepane", nodeToCopy.getParent().getParent());
//WorkspaceDecorator workspaceDecorator = (WorkspaceDecorator) session.getWorkspace();
FolderWorkflow folderWorkflow = (FolderWorkflow) ((HippoWorkspace) session.getWorkspace()).getWorkflowManager().getWorkflow("threepane", nodeToCopy.getParent().getParent());;
String pathToCopy = nodeToCopy.getParent().getPath();
if (pathToCopy.indexOf('.') != -1) {
pathToCopy = pathToCopy.substring(0, pathToCopy.indexOf('.'));
}
LOGGER.info("Copy node {} into {}.{}", nodeToCopy.getName(), pathToCopy,
apiContainerPayload.getVersion());
try {
document = folderWorkflow.copy(nodeToCopy.getName(), pathToCopy + "." + apiContainerPayload.getVersion().toLowerCase(Locale.UK));
//We have to manually clone some nodes of the original content
Node nodeDescription = null;
extractDescription(nodeToCopy, nodeParams, nodeDescription);
extractNodeIcon(nodeToCopy, nodeParams);
} catch (RepositoryException e) {
LOGGER.warn("cant duplicate node {} , using apiContainer data to update/create node", e.getMessage());
document = null;
}
}
return document;
}
public static void extractDescription(Node nodeToCopy, HashMap<String, Object> nodeParams, Node nodeDescription) throws PathNotFoundException, RepositoryException, ValueFormatException {
nodeDescription = extractNodeDescription(nodeToCopy, nodeDescription);
if (nodeDescription!=null && nodeDescription.getProperty(Constants.HIPPO_CONTENT)!=null)
{
nodeParams.put(Constants.OLD_DESCRIPTION,nodeDescription.getProperty(Constants.HIPPO_CONTENT).getString());
}
}
private static Node extractNodeDescription(Node nodeToCopy, Node nodeDescription) {
try
{
nodeDescription=nodeToCopy.getNode("santanderbrxm:description");
} catch (RepositoryException e)
{
LOGGER.info("no description {}",e.getMessage());
}
return nodeDescription;
}
public static void extractNodeIcon(Node nodeToCopy, HashMap<String, Object> nodeParams) throws PathNotFoundException, RepositoryException, ValueFormatException {
Node nodeIcon = extractNodeIcon(nodeToCopy);
if (nodeIcon!=null && nodeIcon.getProperty(Constants.HIPPO_DOCBASE)!=null
&& nodeIcon.getProperty(Constants.HIPPO_VALUES)!=null)
{
nodeParams.put(Constants.OLD_ICON,nodeIcon.getProperty(Constants.HIPPO_DOCBASE).getValue());
nodeParams.put(Constants.OLD_ICON_VALUES,nodeIcon.getProperty(Constants.HIPPO_VALUES).getValues());
nodeParams.put(Constants.OLD_ICON_MODES,nodeIcon.getProperty(Constants.HIPPO_MODES).getValues());
nodeParams.put(Constants.OLD_ICON_FACETS,nodeIcon.getProperty(Constants.HIPPO_FACETS).getValues());
}
}
private static Node extractNodeIcon(Node nodeToCopy) {
Node nodeIcon=null;
try
{
nodeIcon=nodeToCopy.getNode(Constants.SANTANDERBRXM_ICON);
} catch (RepositoryException e)
{
LOGGER.info("no santander icon {}",e.getMessage());
}
return nodeIcon;
}
private static Node setProducerOrganization(String producerOrgId, Session threadSafeSession, Node producerOrganization) throws InvalidQueryException, RepositoryException {
LOGGER.info("product organization id = {}", producerOrgId);
Query prodOrgQuery = threadSafeSession.getWorkspace().getQueryManager().createQuery(
"/jcr:root/content/documents/santander//element"
+ "(*, santanderbrxm:ProducerOrganizationContainer)[@santanderbrxm:idIL ='"
+ producerOrgId + "' and @hippostd:state = 'published']", Query.XPATH);
QueryResult prodOrgQueryResult = prodOrgQuery.execute();
for (NodeIterator nodeIterator = prodOrgQueryResult.getNodes(); nodeIterator.hasNext(); ) {
producerOrganization = nodeIterator.nextNode();
}
return producerOrganization;
}
}