diff --git a/pom.xml b/pom.xml index 73ab38a..ad3c520 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ <packaging>jar</packaging> <groupId>org.silverpeas</groupId> <artifactId>silverpeas-distribution</artifactId> - <version>6.4-SNAPSHOT</version> + <version>6.4.4-SNAPSHOT</version> <name>Distribution of Silverpeas ${project.version}</name> <description> It generates a distribution of Silverpeas ${project.version} for both Unix-like and Windows @@ -83,7 +83,7 @@ <properties> <!-- property used by the CI to both deploy a build version and release the next stable version --> - <next.release>6.4</next.release> + <next.release>6.4.4</next.release> <server.distribution>wildfly26</server.distribution> </properties> diff --git a/src/main/dist/configuration/silverpeas/01-jcrSettings.groovy b/src/main/dist/configuration/silverpeas/01-jcrSettings.groovy index efc1ab8..f1dd303 100644 --- a/src/main/dist/configuration/silverpeas/01-jcrSettings.groovy +++ b/src/main/dist/configuration/silverpeas/01-jcrSettings.groovy @@ -35,39 +35,59 @@ import org.apache.jackrabbit.oak.spi.state.NodeBuilder * before starting Silverpeas in order to retrieve your data. Unlike a first installation, the indexation is * initialized by the migration process itself. For doing, please contact the Silverpeas team. * <li> - * If the JCR is already managed by Oak, then the index definitions is updated from the index configuration file - * SILVERPEAS_HOME/silverpeas/resources/silverpeas-oak.properties. In the case there are some new index definitions, + * If the JCR is already managed by Oak, then both the JCR schema and the index definitions is + * updated from respectively the schema definition file + * SILVERPEAS_HOME/configuration/silverpeas//resources/silverpeas-jcr.cnd and the index configuration + * file SILVERPEAS_HOME/silverpeas/resources/silverpeas-oak.properties. In the case there are some new index definitions, * it is required to use the tool oak-run to reindex all the content of the JCR according to the new index definitions. * </ul> * @author mmoquillon */ -// method to create a definition of an index on the given properties of JCR nodes +// Function to create a definition of an index on the given properties of JCR nodes void createIndexDefinitionOnProperty(NodeBuilder indexRoot, String indexName, String... propertyName) { - if (!indexRoot.hasChildNode(indexName)) { - // additional security to ensure we don't create again the same index definitions - String prop = propertyName.length > 1 ? 'properties' : 'property' - log.info "Create index ${indexName} on ${prop} ${String.join(' and ', propertyName)}" - IndexUtils.createIndexDefinition(indexRoot, indexName, true, false, - Arrays.asList(propertyName), - List.of('slv:simpleDocument')); - } + if (!indexRoot.hasChildNode(indexName)) { + // additional security to ensure we don't create again the same index definitions + String prop = propertyName.length > 1 ? 'properties' : 'property' + log.info "Create index ${indexName} on ${prop} ${String.join(' and ', propertyName)}" + IndexUtils.createIndexDefinition(indexRoot, indexName, true, false, + Arrays.asList(propertyName), + List.of('slv:simpleDocument')); + } } +// Function to create all the index definitions on some custom JCR properties in order to +// optimize the access to the Silverpeas data in the JCR void createWholeIndexDefinitions(Map jcrParams) { - Path jcrIndexDefinitionsPath = - "${settings.CONFIGURATION_HOME}/silverpeas/resources/silverpeas-oak-index.properties".asPath() - Properties indexDefinitions = new Properties() - indexDefinitions.load(Files.newBufferedReader(jcrIndexDefinitionsPath)) - jcr.performOnNodeRootState(jcrParams, { root -> - NodeBuilder index = IndexUtils.getOrCreateOakIndex(root); - indexDefinitions.each {definition -> - String[] np = definition.value.split(' ').collect { it.trim() } - createIndexDefinitionOnProperty(index, definition.key, np); + Path jcrIndexDefinitionsPath = + "${settings.CONFIGURATION_HOME}/silverpeas/resources/silverpeas-oak-index.properties".asPath() + Properties indexDefinitions = new Properties() + indexDefinitions.load(Files.newBufferedReader(jcrIndexDefinitionsPath)) + jcr.performOnNodeRootState(jcrParams, { root -> + NodeBuilder index = IndexUtils.getOrCreateOakIndex(root); + indexDefinitions.each { definition -> + String[] np = definition.value.split(' ').collect { it.trim() } + createIndexDefinitionOnProperty(index, definition.key, np); + } + }) +} + +// Function to setup the JCR schema and the index definitions dedicated to Silverpeas +void setupSchemaAndIndexDefinitions(Map jcrParams) { + log.info 'Register/update the Silverpeas schema into the JCR...' + Path jcrSilverpeasSchemaPath = "${settings.CONFIGURATION_HOME}/silverpeas/resources/silverpeas-jcr.cnd".asPath() + Files.newBufferedReader(jcrSilverpeasSchemaPath).withCloseable { reader -> + jcr.openSession(jcrParams).withCloseable { session -> + CndImporter.registerNodeTypes(reader, session); + } } - }) + + log.info 'Create/update the index definitions for Silverpeas into the JCR...' + createWholeIndexDefinitions(jcrParams) } +// Start the JCR setting for Silverpeas ... + log.info 'Configure the JCR repository...' Path jcrHomePath = settings.JCR_HOME.asPath() @@ -75,106 +95,107 @@ Path jcrConfigurationPath = "${settings.JCR_HOME}/silverpeas-oak.properties".asP Path jcrConfigurationTemplatePath = "${settings.CONFIGURATION_HOME}/silverpeas/resources/silverpeas-oak.properties".asPath() Map jcrParams = ['JCR_HOME': jcrHomePath.toString()] -/* case of a jcr home directory whose the repository is managed by jackrabbit */ +/* + * Case of a jcr home directory whose the repository is managed by jackrabbit: we backup it and + * prepare the Jackrabbit configuration files for the migration to Oak; the migration is expected to + * be done by an external tool, migration-oak + */ Path jcrConfig = "${settings.JCR_HOME}/repository.xml".asPath() if (Files.exists(jcrConfig)) { - Path jackrabbitHomePath = Path.of(jcrHomePath.parent.toString(), 'jackrabbit') - log.info "Rename the Jackrabbit 2 home directory ${jcrHomePath.toString()} to ${jackrabbitHomePath.toString()}..." - - Files.move(jcrHomePath, Path.of(jcrHomePath.parent.toString(), 'jackrabbit')) - - log.info 'Backup the Jackrabbit 2 configuration files and update them for the JCR migration to Oak...' - - String jcrUrl = (settings.JCR_URL ? settings.JCR_URL : settings.DB_URL).toString() - String jcrUser = (settings.JCR_USER ? settings.JCR_USER : settings.DB_USER).toString() - String jcrPassword = (settings.JCR_PASSWORD ? settings.JCR_PASSWORD : settings.DB_PASSWORD).toString() - - Path jackrabbitConfig = jackrabbitHomePath.resolve('repository.xml') - Path jackrabbitConfigBackup = jackrabbitHomePath.resolve('repository.xml.backup') - SAXParserFactory factory = SAXParserFactory.newInstance() - factory.validating = false - factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", - false) - - // backup repository.xml - Files.copy(jackrabbitConfig, jackrabbitConfigBackup, StandardCopyOption.REPLACE_EXISTING) - - // update repository.xml for an eventual migration to oak - def xmlRepositoryConf = new XmlSlurper(factory.newSAXParser()).parse(jackrabbitConfig.toFile()) - def node = xmlRepositoryConf.Workspace.PersistenceManager.param.find { it.@name == 'user'} - if (!node) { - xmlRepositoryConf.Workspace.PersistenceManager.param.find { it.@name == 'driver' }.@value = settings.DB_DRIVER - xmlRepositoryConf.Workspace.PersistenceManager.param.find { it.@name == 'url' }.@value = jcrUrl - xmlRepositoryConf.Workspace.PersistenceManager.appendNode { - param(name: 'user', value: jcrUser) - } - xmlRepositoryConf.Workspace.PersistenceManager.appendNode { - param(name: 'password', value: jcrPassword) - } - xmlRepositoryConf.Versioning.PersistenceManager.param.find { it.@name == 'driver' }.@value = settings.DB_DRIVER - xmlRepositoryConf.Versioning.PersistenceManager.param.find { it.@name == 'url' }.@value = jcrUrl - xmlRepositoryConf.Versioning.PersistenceManager.appendNode { - param(name: 'user', value: jcrUser) - } - xmlRepositoryConf.Versioning.PersistenceManager.appendNode { - param(name: 'password', value: jcrPassword) + Path jackrabbitHomePath = Path.of(jcrHomePath.parent.toString(), 'jackrabbit') + log.info "Rename the Jackrabbit 2 home directory ${jcrHomePath.toString()} to ${jackrabbitHomePath.toString()}..." + + Files.move(jcrHomePath, Path.of(jcrHomePath.parent.toString(), 'jackrabbit')) + + log.info 'Backup the Jackrabbit 2 configuration files and update them for the JCR migration to Oak...' + + String jcrUrl = (settings.JCR_URL ? settings.JCR_URL : settings.DB_URL).toString() + String jcrUser = (settings.JCR_USER ? settings.JCR_USER : settings.DB_USER).toString() + String jcrPassword = (settings.JCR_PASSWORD ? settings.JCR_PASSWORD : settings.DB_PASSWORD).toString() + + Path jackrabbitConfig = jackrabbitHomePath.resolve('repository.xml') + Path jackrabbitConfigBackup = jackrabbitHomePath.resolve('repository.xml.backup') + SAXParserFactory factory = SAXParserFactory.newInstance() + factory.validating = false + factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", + false) + + // backup repository.xml + Files.copy(jackrabbitConfig, jackrabbitConfigBackup, StandardCopyOption.REPLACE_EXISTING) + + // update repository.xml for an eventual migration to oak + def xmlRepositoryConf = new XmlSlurper(factory.newSAXParser()).parse(jackrabbitConfig.toFile()) + def node = xmlRepositoryConf.Workspace.PersistenceManager.param.find { it.@name == 'user' } + if (!node) { + xmlRepositoryConf.Workspace.PersistenceManager.param.find { it.@name == 'driver' }.@value = settings.DB_DRIVER + xmlRepositoryConf.Workspace.PersistenceManager.param.find { it.@name == 'url' }.@value = jcrUrl + xmlRepositoryConf.Workspace.PersistenceManager.appendNode { + param(name: 'user', value: jcrUser) + } + xmlRepositoryConf.Workspace.PersistenceManager.appendNode { + param(name: 'password', value: jcrPassword) + } + xmlRepositoryConf.Versioning.PersistenceManager.param.find { it.@name == 'driver' }.@value = settings.DB_DRIVER + xmlRepositoryConf.Versioning.PersistenceManager.param.find { it.@name == 'url' }.@value = jcrUrl + xmlRepositoryConf.Versioning.PersistenceManager.appendNode { + param(name: 'user', value: jcrUser) + } + xmlRepositoryConf.Versioning.PersistenceManager.appendNode { + param(name: 'password', value: jcrPassword) + } + XmlUtil.serialize(xmlRepositoryConf, new FileWriter(jackrabbitConfig.toFile())) + + // backup workspace.xml + Path jcrWorkspaceConfig = jackrabbitHomePath.resolve(Path.of('workspaces', 'silverpeas', 'workspace.xml')) + Path jcrWorkspaceConfigBackup = jackrabbitHomePath.resolve(Path.of('workspaces', 'silverpeas', 'workspace.xml.backup')) + Files.copy(jcrWorkspaceConfig, jcrWorkspaceConfigBackup, StandardCopyOption.REPLACE_EXISTING) + + // update workspace.xml for an eventual migration to oak + def xmlWorkspaceConf = new XmlSlurper(factory.newSAXParser()).parse(jcrWorkspaceConfig.toFile()) + xmlWorkspaceConf.PersistenceManager.param.find { it.@name == 'driver' }.@value = settings.DB_DRIVER + xmlWorkspaceConf.PersistenceManager.param.find { it.@name == 'url' }.@value = jcrUrl + xmlWorkspaceConf.PersistenceManager.appendNode { + param(name: 'user', value: jcrUser) + } + xmlWorkspaceConf.PersistenceManager.appendNode { + param(name: 'password', value: jcrPassword) + } + XmlUtil.serialize(xmlWorkspaceConf, new FileWriter(jcrWorkspaceConfig.toFile())) } - XmlUtil.serialize(xmlRepositoryConf, new FileWriter(jackrabbitConfig.toFile())) - - // backup workspace.xml - Path jcrWorkspaceConfig = jackrabbitHomePath.resolve(Path.of('workspaces', 'silverpeas', 'workspace.xml')) - Path jcrWorkspaceConfigBackup = jackrabbitHomePath.resolve(Path.of('workspaces', 'silverpeas', 'workspace.xml.backup')) - Files.copy(jcrWorkspaceConfig, jcrWorkspaceConfigBackup, StandardCopyOption.REPLACE_EXISTING) - - // update workspace.xml for an eventual migration to oak - def xmlWorkspaceConf = new XmlSlurper(factory.newSAXParser()).parse(jcrWorkspaceConfig.toFile()) - xmlWorkspaceConf.PersistenceManager.param.find { it.@name == 'driver' }.@value = settings.DB_DRIVER - xmlWorkspaceConf.PersistenceManager.param.find { it.@name == 'url' }.@value = jcrUrl - xmlWorkspaceConf.PersistenceManager.appendNode { - param(name: 'user', value: jcrUser) - } - xmlWorkspaceConf.PersistenceManager.appendNode { - param(name: 'password', value: jcrPassword) - } - XmlUtil.serialize(xmlWorkspaceConf, new FileWriter(jcrWorkspaceConfig.toFile())) - } - - // update the registry of JCR namespaces to replace deprecated empty entry - Path namespacesPath = jackrabbitHomePath.resolve(Path.of('repository', 'namespaces', 'ns_reg.properties')) - Properties namespaces = new Properties() - namespaces.load(new FileInputStream(namespacesPath.toFile())) - String emptyEntry = namespaces.getProperty('') - if (emptyEntry?.isEmpty()) { - namespaces.remove(emptyEntry) - namespaces['.empty.key']='' - namespaces.store(new FileOutputStream(namespacesPath.toFile()), null) - } - - // create the JCR home directory and puts into it the JCR configuration file - log.info 'Create the JCR home directory for Oak and the JCR configuration file from the template...' - service.createDirectory(jcrHomePath, [readable: true, writable: true, executable: true]) - Files.copy(jcrConfigurationTemplatePath, jcrConfigurationPath) - -} /* case of a first installation of Silverpeas */ -else if (! Files.exists(jcrConfigurationPath)) { - // create the JCR home directory and puts into it the JCR configuration file - log.info 'Create the JCR home directory and the JCR configuration file from the template...' - service.createDirectory(jcrHomePath, [readable: true, writable: true, executable: true]) - Files.copy(jcrConfigurationTemplatePath, jcrConfigurationPath) - - // create the JCR schema for Silverpeas - log.info 'Register the Silverpeas schema into the JCR...' - Path jcrSilverpeasSchemaPath = "${settings.CONFIGURATION_HOME}/silverpeas/resources/silverpeas-jcr.cnd".asPath() - Files.newBufferedReader(jcrSilverpeasSchemaPath).withCloseable { reader -> - jcr.openSession(jcrParams).withCloseable { session -> - CndImporter.registerNodeTypes(reader, session); + + // update the registry of JCR namespaces to replace deprecated empty entry + Path namespacesPath = jackrabbitHomePath.resolve(Path.of('repository', 'namespaces', 'ns_reg.properties')) + Properties namespaces = new Properties() + namespaces.load(new FileInputStream(namespacesPath.toFile())) + String emptyEntry = namespaces.getProperty('') + if (emptyEntry?.isEmpty()) { + namespaces.remove(emptyEntry) + namespaces['.empty.key'] = '' + namespaces.store(new FileOutputStream(namespacesPath.toFile()), null) } - } - log.info 'Create the index definitions for Silverpeas into the JCR...' - createWholeIndexDefinitions(jcrParams) -} else { - createWholeIndexDefinitions(jcrParams) + // create the JCR home directory and puts into it the JCR configuration file + log.info 'Create the JCR home directory for Oak and the JCR configuration file from the template...' + service.createDirectory(jcrHomePath, [readable: true, writable: true, executable: true]) + Files.copy(jcrConfigurationTemplatePath, jcrConfigurationPath) + +} +/* + * Case of a first installation of Silverpeas + */ +else if (!Files.exists(jcrConfigurationPath)) { + // create the JCR home directory and puts into it the JCR configuration file + log.info 'Create the JCR home directory and the JCR configuration file from the template...' + service.createDirectory(jcrHomePath, [readable: true, writable: true, executable: true]) + Files.copy(jcrConfigurationTemplatePath, jcrConfigurationPath) + + setupSchemaAndIndexDefinitions(jcrParams) +} +/* + * Case of an update of Silverpeas + */ +else { + setupSchemaAndIndexDefinitions(jcrParams) }