Splitting up content / Bootstrap problem

#1

Hi,

I’m currently facing a problem where new content documents won’t be bootstrapped anymore. Let me explain the scenario:

We currently have a running system with the following folder:
/content/documents/myproject/config/labels
This folder already contains multiple resource bundles and I want to add another one like:
/content/documents/myproject/config/labels/footer-labels

But this does not work :frowning: In other words, the document will not appear on the desired location.
The new file does appears in the hcm:hcm after a deployment.
at /hcm:hcm/hcm:baseline/myproject-hippo/myproject-hippo/myproject-hippo-repository-data-application/hcm-content/content/documents/myproject/config/label/footer-labels.yaml to be precise.

Although there is clearly something going wrong, there are no specific errors for this footer-labels.yaml

There is an interesting error though, which is the following, about the labels.yaml (the folder above our file)

ERROR: Processing 'APPEND' action for content node '/content/documents/myproject/config/label' failed

07.05.2019 15:11:58 [localhost-startStop-1] ERROR [org.onehippo.cm.engine.ConfigurationContentService.apply():174] Processing ‘APPEND’ action for content node ‘/content/documents/myproject/config/label’ failed.
javax.jcr.ItemExistsException: Node already exists at path /content/documents/myproject/config/label
at org.onehippo.cm.engine.JcrContentProcessor.validateAppendAction(JcrContentProcessor.java:110) ~[hippo-repository-engine-5.6.1.jar:5.6.1]
at org.onehippo.cm.engine.JcrContentProcessor.apply(JcrContentProcessor.java:135) ~[hippo-repository-engine-5.6.1.jar:5.6.1]
at org.onehippo.cm.engine.ConfigurationContentService.apply(ConfigurationContentService.java:157) [hippo-repository-engine-5.6.1.jar:5.6.1]
at org.onehippo.cm.engine.ConfigurationContentService.apply(ConfigurationContentService.java:87) [hippo-repository-engine-5.6.1.jar:5.6.1]
at org.onehippo.cm.engine.ConfigurationServiceImpl.applyContent(ConfigurationServiceImpl.java:666) [hippo-repository-engine-5.6.1.jar:5.6.1]
at org.onehippo.cm.engine.ConfigurationServiceImpl.init(ConfigurationServiceImpl.java:216) [hippo-repository-engine-5.6.1.jar:5.6.1]
at org.onehippo.cm.engine.ConfigurationServiceImpl.start(ConfigurationServiceImpl.java:122) [hippo-repository-engine-5.6.1.jar:5.6.1]
at com.onehippo.repository.HippoEnterpriseRepository.initializeConfiguration(HippoEnterpriseRepository.java:178) [hippo-enterprise-repository-engine-5.6.1.jar:5.6.1]
at org.hippoecm.repository.LocalHippoRepository.initialize(LocalHippoRepository.java:292) [hippo-repository-engine-5.6.1.jar:5.6.1]
at com.onehippo.repository.HippoEnterpriseRepository.create(HippoEnterpriseRepository.java:63) [hippo-enterprise-repository-engine-5.6.1.jar:5.6.1]
at com.onehippo.repository.HippoEnterpriseRepository.create(HippoEnterpriseRepository.java:53) [hippo-enterprise-repository-engine-5.6.1.jar:5.6.1]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_212]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_212]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_212]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_212]
at org.hippoecm.repository.HippoRepositoryFactory.getHippoRepository(HippoRepositoryFactory.java:147) [hippo-repository-connector-5.6.1.jar:5.6.1]
at org.hippoecm.repository.RepositoryServlet.init(RepositoryServlet.java:184) [hippo-repository-servlets-5.6.1.jar:5.6.1]
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1142) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1089) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:983) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4956) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5270) [catalina.jar:8.5.40]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:8.5.40]
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754) [catalina.jar:8.5.40]
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730) [catalina.jar:8.5.40]
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734) [catalina.jar:8.5.40]
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:980) [catalina.jar:8.5.40]
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1851) [catalina.jar:8.5.40]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_212]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_212]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_212]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]

This error is quite explainable, because in the beginning of our project we’ve had a large labels.yaml which not only consists of a folder, but also all the resources bundles underneath. Because this was not really the way we like to save files, we decided to split this up. Also because the resources bundles changed, and we wanted to update them locally as well. So we moved all resources bundles under /labels to our repository-data-development module. So since that moment our labels.yaml changed and starts throwing this non-sense error (in my eyes).

I’m not really sure how we could have done this without getting this error. Before Hippo 12 we could play around with the hippo:initialize nodes, but this is not possible anymore since the switch to yaml.

The error of the labels.yaml looks to be effecting the child nodes as well, although that’s just my assumption. Hope someone could make help me out here!

Thanks in advance for the effort at least :wink:

Cheers,
Jesper

PS: I know about the hcm-actions, but reloading the labels node will remove all existing labels on production as well, this is something we would like to avoid :slight_smile:

#2

Are you sure you’re not being fooled by a “label” vs. “labels” typo?

#3

I’m pretty sure it’s not a typo, because locally it works but on the QA environment it doesn’t. The main difference is the persistence database. So in other words, only with existing content it fails.
Thanks for thinking with me though.

#4

What might be happening is that you need to reload that content [1]. Content is only loaded once, and thereafter it will not be loaded again from the project files. You can add an explicit directive to override that behavior. This is because content is thought to belong to the instance, except for initial bootstrap. If you need those files managed from the project you should mark them as config.

[1] https://documentation.bloomreach.com/library/concepts/configuration-management/manage-content.html

#5

Hi Jasper,
All I can do is reload the labels folder, but then I will lose all the files in the folder :frowning: This is all content, and we have been treating it like content, and would like to continue so as well. Updates on the label files have been done by updaters.
The only ‘out of the ordinary’ we’ve done, is restructure our yaml files for local/development purposes. These did not have effect on the other environments, besides the error. Are those changes not supported? I feel like I have limited options with the yaml configuration compared to the config before Hippo 12. It looks like this restructure has made it impossible to load nodes under the nodes which have changed yaml files. I don’t get why… It looks like the only option is to move all labels, reload the labels folder and then move the labels back. Do you see any other options?

Cheers,
Jesper

#6

Since you restructured the files it may be confused wrt which file controls what…but I’m not sure.

#7

It does appear that there’s an inconsistency in your original post between “label” and “labels”. The exception message uses the singular form but your second paragraph uses the plural form.

Assuming that’s not the issue, I think there are two possible solutions. Either one should work, and the one you pick would depend on how your devs and testers work together and how they use the QA environment.

Option A: Add a “reload” action for this path in your development module. Here’s the rationale:

  1. From the perspective of the system you’re trying to bootstrap, that node already exists. It doesn’t really matter how that came to be true – the bootstrap mechanism fails fast on content, on the assumption that this is user data that must be preserved at all costs.
  2. The development module should only be packaged and deployed to systems that are under the control of developers and used for testing purposes. It is normal to want to replace content on those systems with updated test data. In this case, that’s exactly what you’re trying to do – (re)load new data files to replace the content at that location.
  3. It’s reasonable to want testers modify content over time to develop new manual-testing scenarios on the running system. Classifying these paths as content means those testers don’t have to worry that a new deployment will reset the data to whatever the developers are using.
  4. Developers can choose to occasionally harvest updated test content from the test environment and include it in their development project, where it’s more common to start from a totally clean repository. If they don’t do that, any new environments and automated tests running on them will not take advantage of whatever changes were made on the QA environment.

Option B: In the development module, reclassify these paths as config and manage the data in the dev project with version control etc.

  1. Again, this will only affect systems where the development module is deployed, so you don’t need to worry about your production system having its data reset.
  2. Once the paths are reclassified as config, the bootstrap system has much more detailed information about what’s happening with the data and is more aggressive about keeping the JCR nodes up to date.
  3. Testers can still modify the content and it will be left as-is on the environment until a developer specifically updates a particular node and redeploys. At that point, that node and its descendants will be reset to whatever is in the deployment package. That shifts more control to the developers at the expense of manual testers, who might need to reapply their changes in the QA environment after a deployment.

I think the only mystery here is why the bootstrapping system is trying to apply the content definition for this path at all. We normally record all paths where a content definition has been previously applied in ‘/hcm:hcm/hcm:baseline/hcm:content/hcm:contentPathsApplied’. Is it possible that someone manually added the ‘/content/documents/myproject/config/label’ folder on the QA environment before it was ever added to the dev project? That would explain the error message. If that’s the case, the restructuring of the files is irrelevant. Once we detect a problem on a node, the bootstrapping system stops processing any descendants, on the theory that we don’t really know what should happen anymore and should avoid making things worse.

#9

Hi Peter,

Thanks for your reply, although this was not exactly the solution I was looking for, you did mention hcm:contentPathsApplied, which made me think. Why is there no /content/documents/gvbmuvhippo/config/label in there?
The reason for that is, that the label.yaml didn’t contain all the individual resource bundles in the first place. They were even on a higher level, inside the config.yaml. This config.yaml contained all nodes below, including the label folder! This is why Hippo kept telling me that the Node already exists at path /content/documents/myproject/config/label. Because the label.yaml was considered ‘new’. And like you’ve said, since the label folder is failing, it will not even consider trying the files/nodes below. So the solution for my problem, is to tell Hippo that I’ve already loaded the labels folder by setting an entry in the hcm:contentPathsApplied my self.

Again thanks for thinking with me!

Cheers,
Jesper