You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2016/11/11 06:09:37 UTC
svn commit: r1769248 - in /sling/trunk/installer/factories/model: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/sling/ src/main/java/org/apache/sling/installer/
src/main/java/org/apache/sling/ins...
Author: cziegeler
Date: Fri Nov 11 06:09:36 2016
New Revision: 1769248
URL: http://svn.apache.org/viewvc?rev=1769248&view=rev
Log:
Add prototype of a installer support for provisioning models
Added:
sling/trunk/installer/factories/model/
sling/trunk/installer/factories/model/pom.xml (with props)
sling/trunk/installer/factories/model/src/
sling/trunk/installer/factories/model/src/main/
sling/trunk/installer/factories/model/src/main/java/
sling/trunk/installer/factories/model/src/main/java/org/
sling/trunk/installer/factories/model/src/main/java/org/apache/
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractModelTask.java (with props)
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/InstallModelTask.java (with props)
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTaskFactory.java (with props)
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTransformer.java (with props)
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/RepositoryAccess.java (with props)
sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallModelTask.java (with props)
Added: sling/trunk/installer/factories/model/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/installer/factories/model/pom.xml?rev=1769248&view=auto
==============================================================================
--- sling/trunk/installer/factories/model/pom.xml (added)
+++ sling/trunk/installer/factories/model/pom.xml Fri Nov 11 06:09:36 2016
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>29</version>
+ <relativePath/>
+ </parent>
+
+ <artifactId>org.apache.sling.installer.factory.model</artifactId>
+ <version>0.1.0-SNAPSHOT</version>
+ <packaging>bundle</packaging>
+
+ <name>Apache Sling Installer Provisioning Model Support</name>
+ <description>
+ Provides support for the provisioning model to the Apache Sling OSGi installer
+ </description>
+
+ <properties>
+ <sling.java.version>8</sling.java.version>
+ </properties>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/installer/factories/model</connection>
+ <developerConnection> scm:svn:https://svn.apache.org/repos/asf/sling/trunk/installer/factories/model</developerConnection>
+ <url>http://svn.apache.org/viewvc/sling/trunk/installer/factories/model</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.installer.core</artifactId>
+ <version>3.8.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.jcr.api</artifactId>
+ <version>2.4.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.jcr.repoinit</artifactId>
+ <version>1.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.repoinit.parser</artifactId>
+ <version>1.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.settings</artifactId>
+ <version>1.2.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.provisioning.model</artifactId>
+ <version>1.7.0</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
Propchange: sling/trunk/installer/factories/model/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/factories/model/pom.xml
------------------------------------------------------------------------------
svn:keywords = Id
Added: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractModelTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractModelTask.java?rev=1769248&view=auto
==============================================================================
--- sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractModelTask.java (added)
+++ sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractModelTask.java Fri Nov 11 06:09:36 2016
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.installer.factory.model.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class for the tasks.
+ */
+public abstract class AbstractModelTask extends InstallTask {
+
+ /** Logger. */
+ protected final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ private final BundleContext bundleContext;
+
+ private final Map<ServiceReference<?>, Object> services = new HashMap<>();
+
+ public AbstractModelTask(final TaskResourceGroup group,
+ final BundleContext bundleContext) {
+ super(group);
+ this.bundleContext = bundleContext;
+ }
+
+ protected void cleanup() {
+ for(final ServiceReference<?> r : this.services.keySet()) {
+ this.bundleContext.ungetService(r);
+ }
+ this.services.clear();
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T> T getService(final Class<T> type) {
+ T service = null;
+ final ServiceReference<T> reference = this.bundleContext.getServiceReference(type);
+ if ( reference != null ) {
+ service = (T)this.services.get(reference);
+ if ( service == null ) {
+ service = this.bundleContext.getService(reference);
+ if ( service != null ) {
+ this.services.put(reference, service);
+ } else {
+ }
+ }
+ }
+ if ( service == null ) {
+ logger.error("Unable to get OSGi service " + type.getName());
+ }
+ return service;
+ }
+
+ protected String getModelName() {
+ final String url = this.getResource().getURL();
+ final int lastSlash = url.lastIndexOf('/');
+ return lastSlash == -1 ? url : url.substring(lastSlash + 1);
+ }
+}
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractModelTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/AbstractModelTask.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/InstallModelTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/InstallModelTask.java?rev=1769248&view=auto
==============================================================================
--- sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/InstallModelTask.java (added)
+++ sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/InstallModelTask.java Fri Nov 11 06:09:36 2016
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.installer.factory.model.impl;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.api.OsgiInstaller;
+import org.apache.sling.installer.api.tasks.InstallationContext;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
+import org.apache.sling.provisioning.model.Artifact;
+import org.apache.sling.provisioning.model.ArtifactGroup;
+import org.apache.sling.provisioning.model.Configuration;
+import org.apache.sling.provisioning.model.Feature;
+import org.apache.sling.provisioning.model.Model;
+import org.apache.sling.provisioning.model.ModelUtility;
+import org.apache.sling.provisioning.model.RunMode;
+import org.apache.sling.provisioning.model.Section;
+import org.apache.sling.provisioning.model.Traceable;
+import org.apache.sling.provisioning.model.io.ModelReader;
+import org.apache.sling.repoinit.parser.RepoInitParser;
+import org.apache.sling.repoinit.parser.RepoInitParsingException;
+import org.apache.sling.repoinit.parser.operations.Operation;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This task installs model resources.
+ */
+public class InstallModelTask extends AbstractModelTask {
+
+ private final Set<String> activeRunModes;
+
+ private final SlingRepository repository;
+
+ private final JcrRepoInitOpsProcessor repoInitProcessor;
+
+ private final RepoInitParser repoInitParser;
+
+ public InstallModelTask(final TaskResourceGroup group,
+ final Set<String> runModes,
+ final SlingRepository repository,
+ final JcrRepoInitOpsProcessor repoInitProcessor,
+ final RepoInitParser repoInitParser,
+ final BundleContext bundleContext) {
+ super(group, bundleContext);
+ this.activeRunModes = runModes;
+ this.repository = repository;
+ this.repoInitProcessor = repoInitProcessor;
+ this.repoInitParser = repoInitParser;
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void execute(final InstallationContext ctx) {
+ try {
+ final TaskResource resource = this.getResource();
+ final String modelTxt = (String) resource.getAttribute(ModelTransformer.ATTR_MODEL);
+ if ( modelTxt == null ) {
+ ctx.log("Unable to install model resource {} : no model found", this.getResource());
+ this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+ } else {
+ final String name = this.getModelName();
+ final Result result = this.transform(name, modelTxt);
+ if ( result == null ) {
+ ctx.log("Unable to install model resource {} : unable to create resources", this.getResource());
+ this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+ } else {
+ // repo init first
+ if ( result.repoinit != null ) {
+ List<Operation> ops = null;
+ try ( final Reader r = new StringReader(result.repoinit) ) {
+ ops = this.repoInitParser.parse(r);
+ } catch (final IOException | RepoInitParsingException e) {
+ logger.error("Unable to parse repoinit block.", e);
+ ctx.log("Unable to install model resource {} : unable parse repoinit block.", this.getResource());
+ this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+ return;
+ }
+
+ // login admin is required for repo init
+ Session session = null;
+ try {
+ session = this.repository.loginAdministrative(null);
+ this.repoInitProcessor.apply(session, ops);
+ session.save();
+ } catch ( final RepositoryException re) {
+ logger.error("Unable to process repoinit block.", re);
+ ctx.log("Unable to install model resource {} : unable to process repoinit block.", this.getResource());
+ this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+ return;
+
+ } finally {
+ if ( session != null ) {
+ session.logout();
+ }
+ }
+ }
+ if ( !result.resources.isEmpty() ) {
+ final OsgiInstaller installer = this.getService(OsgiInstaller.class);
+ if ( installer != null ) {
+ installer.registerResources("model-" + name, result.resources.toArray(new InstallableResource[result.resources.size()]));
+ this.getResourceGroup().setFinishState(ResourceState.INSTALLED);
+ } else {
+ ctx.log("Unable to install model resource {} : unable to get OSGi installer", this.getResource());
+ this.getResourceGroup().setFinishState(ResourceState.IGNORED);
+ }
+ }
+ }
+ }
+ } finally {
+ this.cleanup();
+ }
+ }
+
+ public static final class Result {
+ public final List<InstallableResource> resources = new ArrayList<>();
+ public String repoinit;
+ }
+
+ private Result transform(final String name, final String modelText) {
+ try ( final Reader reader = new StringReader(modelText)) {
+ final Model model = ModelUtility.getEffectiveModel(ModelReader.read(reader, name));
+
+ final List<ArtifactDescription> files = new ArrayList<>();
+
+ Map<Traceable, String> errors = collectArtifacts(model, files);
+ if ( errors == null ) {
+ final Result result = new Result();
+ for(final ArtifactDescription desc : files) {
+ if ( desc.artifactFile != null ) {
+ final InputStream is = new FileInputStream(desc.artifactFile);
+ final String digest = String.valueOf(desc.artifactFile.lastModified());
+ // handle start level
+ final Dictionary<String, Object> dict = new Hashtable<String, Object>();
+ if ( desc.startLevel > 0 ) {
+ dict.put(InstallableResource.BUNDLE_START_LEVEL, desc.startLevel);
+ }
+ dict.put(InstallableResource.RESOURCE_URI_HINT, desc.artifactFile.toURI().toString());
+
+ result.resources.add(new InstallableResource("/" + desc.artifactFile.getName(), is, dict, digest,
+ InstallableResource.TYPE_FILE, null));
+ } else if ( desc.cfg != null ) {
+ final String id = (desc.cfg.getFactoryPid() != null ? desc.cfg.getFactoryPid() + "-" + desc.cfg.getPid() : desc.cfg.getPid());
+ result.resources.add(new InstallableResource("/" + id + ".config",
+ null,
+ desc.cfg.getProperties(),
+ null,
+ InstallableResource.TYPE_CONFIG, null));
+
+ } else if ( desc.section != null ) {
+ result.repoinit = desc.section.getContents();
+ }
+ }
+ return result;
+ }
+ logger.warn("Errors during parsing model file {} : {}", name, errors.values());
+ } catch ( final IOException ioe) {
+ logger.warn("Unable to read potential model file " + name, ioe);
+ }
+ return null;
+ }
+
+ private static class ArtifactDescription {
+ public int startLevel;
+ public File artifactFile;
+ public Configuration cfg;
+ public Section section;
+ }
+
+ private Map<Traceable, String> collectArtifacts(final Model effectiveModel, final List<ArtifactDescription> files) {
+ final RepositoryAccess repo = new RepositoryAccess();
+ final Map<Traceable, String> errors = new HashMap<>();
+ for(final Feature f : effectiveModel.getFeatures()) {
+ if ( f.isSpecial() ) {
+ continue;
+ }
+ for(final Section section : f.getAdditionalSections()) {
+ final ArtifactDescription desc = new ArtifactDescription();
+ desc.section = section;
+ files.add(desc);
+ }
+ for(final RunMode mode : f.getRunModes()) {
+ if ( mode.isSpecial() ) {
+ continue;
+ }
+ if ( mode.isActive(this.activeRunModes) ) {
+ for(final ArtifactGroup group : mode.getArtifactGroups()) {
+ for(final Artifact artifact : group) {
+ final File file = repo.get(artifact);
+ if ( file == null ) {
+ errors.put(artifact, "Artifact " + artifact.toMvnUrl() + " not found.");
+ } else {
+ final ArtifactDescription desc = new ArtifactDescription();
+ desc.artifactFile = file;
+ desc.startLevel = group.getStartLevel();
+ files.add(desc);
+ }
+ }
+ }
+ for(final Configuration cfg : mode.getConfigurations() ) {
+ if ( cfg.isSpecial() ) {
+ continue;
+ }
+ final ArtifactDescription desc = new ArtifactDescription();
+ desc.cfg = cfg;
+ files.add(desc);
+ }
+ }
+ }
+ }
+ return errors.isEmpty() ? null : errors;
+ }
+
+ @Override
+ public String getSortKey() {
+ return "30-" + getModelName();
+ }
+}
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/InstallModelTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/InstallModelTask.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTaskFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTaskFactory.java?rev=1769248&view=auto
==============================================================================
--- sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTaskFactory.java (added)
+++ sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTaskFactory.java Fri Nov 11 06:09:36 2016
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.installer.factory.model.impl;
+
+
+import org.apache.sling.installer.api.tasks.InstallTask;
+import org.apache.sling.installer.api.tasks.InstallTaskFactory;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResource;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.repoinit.JcrRepoInitOpsProcessor;
+import org.apache.sling.repoinit.parser.RepoInitParser;
+import org.apache.sling.settings.SlingSettingsService;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This task factory process model resources detected by
+ * the {@link ModelTransformer}.
+ */
+@Component(service = InstallTaskFactory.class)
+public class ModelTaskFactory implements InstallTaskFactory {
+
+ /** Logger. */
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Reference
+ private SlingSettingsService settings;
+
+ @Reference
+ private SlingRepository repository;
+
+ @Reference
+ private JcrRepoInitOpsProcessor repoInitProcessor;
+
+ @Reference
+ private RepoInitParser repoInitParser;
+
+ private BundleContext bundleContext;
+
+ @Activate
+ private void activate(final BundleContext ctx) {
+ this.bundleContext = ctx;
+ }
+
+ @Override
+ public InstallTask createTask(final TaskResourceGroup group) {
+ final TaskResource rsrc = group.getActiveResource();
+ if ( !ModelTransformer.TYPE_PROV_MODEL.equals(rsrc.getType()) ) {
+ return null;
+ }
+ if (rsrc.getState() == ResourceState.UNINSTALL ) {
+ logger.info("Uninstalling {}", rsrc.getEntityId());
+
+ return new UninstallModelTask(group, bundleContext);
+ }
+ logger.info("Installing {}", rsrc.getEntityId());
+ return new InstallModelTask(group,
+ this.settings.getRunModes(),
+ this.repository,
+ this.repoInitProcessor,
+ this.repoInitParser,
+ this.bundleContext);
+ }
+}
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTaskFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTaskFactory.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTransformer.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTransformer.java?rev=1769248&view=auto
==============================================================================
--- sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTransformer.java (added)
+++ sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTransformer.java Fri Nov 11 06:09:36 2016
@@ -0,0 +1,131 @@
+package org.apache.sling.installer.factory.model.impl;/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.sling.installer.api.InstallableResource;
+import org.apache.sling.installer.api.tasks.RegisteredResource;
+import org.apache.sling.installer.api.tasks.ResourceTransformer;
+import org.apache.sling.installer.api.tasks.TransformationResult;
+import org.apache.sling.provisioning.model.Configuration;
+import org.apache.sling.provisioning.model.Feature;
+import org.apache.sling.provisioning.model.Model;
+import org.apache.sling.provisioning.model.ModelUtility;
+import org.apache.sling.provisioning.model.RunMode;
+import org.apache.sling.provisioning.model.Section;
+import org.apache.sling.provisioning.model.Traceable;
+import org.apache.sling.provisioning.model.io.ModelReader;
+import org.apache.sling.provisioning.model.io.ModelWriter;
+import org.osgi.framework.Version;
+import org.osgi.service.component.annotations.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This transformer detects a file with the ending ".model" containing
+ * a provisioning model.
+ */
+@Component(service = ResourceTransformer.class)
+public class ModelTransformer implements ResourceTransformer {
+
+ public static final String TYPE_PROV_MODEL = "provisioningmodel";
+
+ public static final String ATTR_MODEL = "model";
+
+ /** Logger. */
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ @Override
+ public TransformationResult[] transform(final RegisteredResource resource) {
+ if ( resource.getType().equals(InstallableResource.TYPE_FILE) && resource.getURL().endsWith(".model") ) {
+ try ( final Reader reader = new InputStreamReader(resource.getInputStream(), "UTF-8") ) {
+ final Model model = ModelReader.read(reader, resource.getURL());
+
+ Map<Traceable, String> errors = ModelUtility.validate(model);
+ if ( errors == null ) {
+ try {
+ final Model effectiveModel = ModelUtility.getEffectiveModel(model);
+
+ errors = validate(effectiveModel);
+ if ( errors == null ) {
+
+ final Feature f = effectiveModel.getFeatures().get(0);
+ final TransformationResult tr = new TransformationResult();
+ tr.setId(f.getName());
+ tr.setResourceType(TYPE_PROV_MODEL);
+ tr.setVersion(new Version(f.getVersion()));
+
+ try ( final StringWriter sw = new StringWriter()) {
+ ModelWriter.write(sw, effectiveModel);
+ tr.setAttributes(Collections.singletonMap(ATTR_MODEL, (Object)sw.toString()));
+ }
+ return new TransformationResult[] {tr};
+ }
+ } catch ( final IllegalArgumentException iae ) {
+ errors = Collections.singletonMap((Traceable)model, iae.getMessage());
+ }
+ }
+ if ( errors != null ) {
+ logger.warn("Errors during parsing model at {} : {}", resource.getURL(), errors.values());
+ }
+
+ } catch ( final IOException ioe) {
+ logger.info("Unable to read model from " + resource.getURL(), ioe);
+ }
+ }
+ return null;
+ }
+
+ private Map<Traceable, String> validate(final Model effectiveModel) {
+ if ( effectiveModel.getFeatures().size() != 1 ) {
+ return Collections.singletonMap((Traceable)effectiveModel, "Model should only contain a single feature.");
+ }
+ final Feature feature = effectiveModel.getFeatures().get(0);
+ if ( feature.isSpecial() ) {
+ return Collections.singletonMap((Traceable)feature, "Feature must not be special.");
+ }
+ if ( feature.getVersion() == null ) {
+ return Collections.singletonMap((Traceable)feature, "Feature must have a version.");
+ }
+ for(final Section section : feature.getAdditionalSections()) {
+ if ( !"repoinit".equals(section.getName()) ) {
+ return Collections.singletonMap((Traceable)section, "Additional section not supported.");
+ }
+ }
+ for(final RunMode mode : feature.getRunModes()) {
+ if ( mode.isSpecial() ) {
+ return Collections.singletonMap((Traceable)mode, "RunMode must not be special.");
+ }
+ for(final Configuration cfg : mode.getConfigurations()) {
+ if ( cfg.isSpecial() ) {
+ return Collections.singletonMap((Traceable)cfg, "Configuration must not be special.");
+ }
+ }
+ }
+
+ return null;
+ }
+
+}
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTransformer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/ModelTransformer.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/RepositoryAccess.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/RepositoryAccess.java?rev=1769248&view=auto
==============================================================================
--- sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/RepositoryAccess.java (added)
+++ sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/RepositoryAccess.java Fri Nov 11 06:09:36 2016
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.installer.factory.model.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.ProcessBuilder.Redirect;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sling.provisioning.model.Artifact;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Helper class for getting maven artifacts.
+ *
+ * It is a simple class assuming that the mvn command is installed
+ * and that the .m2 directory is in the home directory of the current
+ * user.
+ */
+public class RepositoryAccess {
+
+ /**
+ * A logger.
+ */
+ private final Logger logger = LoggerFactory.getLogger(this.getClass());
+
+ /**
+ * The .m2 directory.
+ */
+ private final String repoHome;
+
+ /**
+ * Create a new instance.
+ */
+ public RepositoryAccess() {
+ this.repoHome = System.getProperty("user.home") + "/.m2/repository/";
+ }
+
+ /**
+ * Get the file for an artifact
+ * @param artifact The artifact
+ * @return The file or {@code null}
+ */
+ public File get(final Artifact artifact) {
+
+ final File artifactFile = this.getArtifact(artifact);
+
+ if ( artifactFile == null ) {
+ return null;
+ }
+ logger.info("Responding for {} with {}", artifact, artifactFile);
+ return artifactFile;
+ }
+
+ private File getArtifact(final Artifact artifact) {
+ logger.info("Requesting {}", artifact);
+
+ final String filePath = (this.repoHome.concat(artifact.getRepositoryPath())).replace('/', File.separatorChar);
+ logger.info("Trying to fetch artifact from {}", filePath);
+ final File f = new File(filePath);
+ if ( !f.exists() || !f.isFile() || !f.canRead() ) {
+ logger.info("Trying to download {}", artifact.getRepositoryPath());
+ try {
+ this.downloadArtifact(artifact);
+ } catch ( final IOException ioe ) {
+ logger.debug("Error downloading file.", ioe);
+ }
+ if ( !f.exists() || !f.isFile() || !f.canRead() ) {
+ logger.info("Artifact not found {}", artifact);
+
+ return null;
+ }
+ }
+ return f;
+ }
+
+ /**
+ * Download artifact from maven
+ * @throws IOException
+ */
+ private void downloadArtifact(final Artifact artifact) throws IOException {
+ // create fake pom
+ final Path dir = Files.createTempDirectory(null);
+ final List<String> lines = new ArrayList<String>();
+ lines.add("<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">");
+ lines.add(" <modelVersion>4.0.0</modelVersion>");
+ lines.add(" <groupId>org.apache.sling</groupId>");
+ lines.add(" <artifactId>temp-artifact</artifactId>");
+ lines.add(" <version>1-SNAPSHOT</version>");
+ lines.add(" <dependencies>");
+ lines.add(" <dependency>");
+ lines.add(" <groupId>" + artifact.getGroupId() + "</groupId>");
+ lines.add(" <artifactId>" + artifact.getArtifactId() + "</artifactId>");
+ lines.add(" <version>" + artifact.getVersion() + "</version>");
+ if ( artifact.getClassifier() != null ) {
+ lines.add(" <classifier>" + artifact.getClassifier() + "</classifier>");
+ }
+ if ( !"bundle".equals(artifact.getType()) && !"jar".equals(artifact.getType()) ) {
+ lines.add(" <type>" + artifact.getType() + "</type>");
+ }
+ lines.add(" <scope>provided</scope>");
+ lines.add(" </dependency>");
+ lines.add(" </dependencies>");
+ lines.add("</project>");
+ logger.info("Writing pom to {}", dir);
+ Files.write(dir.resolve("pom.xml"), lines);
+
+ final File output = dir.resolve("output.txt").toFile();
+ final File error = dir.resolve("error.txt").toFile();
+
+ // invoke maven
+ logger.info("Invoking maven...");
+ final ProcessBuilder pb = new ProcessBuilder("mvn", "verify");
+ pb.directory(dir.toFile());
+ pb.redirectOutput(Redirect.to(output));
+ pb.redirectError(Redirect.to(error));
+
+ final Process p = pb.start();
+ try {
+ p.waitFor();
+ } catch (final InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+}
\ No newline at end of file
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/RepositoryAccess.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/RepositoryAccess.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Added: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallModelTask.java
URL: http://svn.apache.org/viewvc/sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallModelTask.java?rev=1769248&view=auto
==============================================================================
--- sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallModelTask.java (added)
+++ sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallModelTask.java Fri Nov 11 06:09:36 2016
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.installer.factory.model.impl;
+
+import org.apache.sling.installer.api.OsgiInstaller;
+import org.apache.sling.installer.api.tasks.InstallationContext;
+import org.apache.sling.installer.api.tasks.ResourceState;
+import org.apache.sling.installer.api.tasks.TaskResourceGroup;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This task uninstalls model resources.
+ */
+public class UninstallModelTask extends AbstractModelTask {
+
+ public UninstallModelTask(final TaskResourceGroup group,
+ final BundleContext bundleContext) {
+ super(group, bundleContext);
+ }
+
+ @Override
+ public void execute(final InstallationContext ctx) {
+ try {
+ final OsgiInstaller installer = this.getService(OsgiInstaller.class);
+ if ( installer == null ) {
+ ctx.log("Unable to get OSGi Installer service!");
+ } else {
+ installer.registerResources("model-" + getModelName(), null);
+ this.getResourceGroup().setFinishState(ResourceState.UNINSTALLED);
+ }
+ } finally {
+ this.cleanup();
+ }
+ }
+
+ @Override
+ public String getSortKey() {
+ return "31-" + getModelName();
+ }
+}
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallModelTask.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/installer/factories/model/src/main/java/org/apache/sling/installer/factory/model/impl/UninstallModelTask.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url