Search in sources :

Example 11 with Agent

use of io.fabric8.agent.service.Agent in project fabric8 by jboss-fuse.

the class FabricTestSupport method containerSetProfile.

/**
 * Cleans a containers profile by switching to default profile and resetting the profile.
 */
private boolean containerSetProfile(FabricService fabricService, CuratorFramework curator, String containerName, String profileName, Boolean waitForProvision) throws Exception {
    System.out.println("Switching profile: " + profileName + " on container:" + containerName);
    Container container = fabricService.getContainer(containerName);
    Version version = container.getVersion();
    Profile[] profiles = new Profile[] { version.getRequiredProfile(profileName) };
    Profile[] currentProfiles = container.getProfiles();
    Arrays.sort(profiles);
    Arrays.sort(currentProfiles);
    boolean same = true;
    if (profiles.length != currentProfiles.length) {
        same = false;
    } else {
        for (int i = 0; i < currentProfiles.length; i++) {
            if (!currentProfiles[i].equals(profiles[i])) {
                same = false;
            }
        }
    }
    if (!same && waitForProvision) {
        // This is required so that waitForProvisionSuccess doesn't retrun before the deployment agent kicks in.
        ZooKeeperUtils.setData(curator, ZkPath.CONTAINER_PROVISION_RESULT.getPath(containerName), "switching profile");
        container.setProfiles(profiles);
        Provision.containersStatus(Arrays.asList(container), "success", PROVISION_TIMEOUT);
    }
    return same;
}
Also used : Container(io.fabric8.api.Container) Version(io.fabric8.api.Version) Profile(io.fabric8.api.Profile)

Example 12 with Agent

use of io.fabric8.agent.service.Agent in project fabric8 by jboss-fuse.

the class DeploymentAgent method createDownloadExecutor.

protected ScheduledExecutorService createDownloadExecutor() {
    // TODO: this should not be loaded from a static file
    // TODO: or at least from the bundle context, but preferably from the config
    String size = DEFAULT_DOWNLOAD_THREADS;
    try {
        Properties customProps = new Properties(new File(KARAF_BASE + File.separator + "etc" + File.separator + "custom.properties"));
        size = customProps.getProperty(DOWNLOAD_THREADS, size);
    } catch (Exception e) {
    // ignore
    }
    int num = Integer.parseInt(size);
    LOGGER.info("Creating fabric-agent-download thread pool with size: {}", num);
    return Executors.newScheduledThreadPool(num, new NamedThreadFactory("fabric-agent-download"));
}
Also used : NamedThreadFactory(io.fabric8.utils.NamedThreadFactory) Properties(org.apache.felix.utils.properties.Properties) File(java.io.File) ConfigurationException(org.osgi.service.cm.ConfigurationException) BundleException(org.osgi.framework.BundleException) IOException(java.io.IOException)

Example 13 with Agent

use of io.fabric8.agent.service.Agent in project fabric8 by jboss-fuse.

the class DeploymentAgent method handleRestartJvmFlag.

/**
 * Adds support for a directive to force a restart upon the first assignment of a specific profile to a container.
 * It creates an entry in zk so that a subsequent modification to the same profile, will not trigger a jvm restart.
 * The behavior is useful for situation when a profile provision .jars in lib/ folder, that are picked up only at
 * jvm boot time.
 *
 * @param profile
 * @param restart
 * @return
 */
protected boolean handleRestartJvmFlag(Profile profile, AtomicBoolean restart) {
    boolean result = false;
    List<String> profilesRequiringRestart = new ArrayList<>();
    ServiceReference<CuratorFramework> curatorServiceReference = systemBundleContext.getServiceReference(CuratorFramework.class);
    ServiceReference<FabricService> fabricServiceReference = systemBundleContext.getServiceReference(FabricService.class);
    if (curatorServiceReference != null && fabricServiceReference != null) {
        CuratorFramework curator = systemBundleContext.getService(curatorServiceReference);
        FabricService fs = systemBundleContext.getService(fabricServiceReference);
        String currentContainerName = fs.getCurrentContainerName();
        List<String> activeProfiles = fs.getCurrentContainer().getProfileIds();
        // check for jvm restart requests
        Map<String, String> agentProperties = profile.getConfiguration("io.fabric8.agent");
        Map<String, String> jvmRestartEntries = new HashMap<>();
        for (String key : agentProperties.keySet()) {
            if (key.startsWith("io.fabric8.agent.forceOneTimeJVMRestart")) {
                jvmRestartEntries.put(key, agentProperties.get(key));
                LOGGER.info("Found a profile carrying a one-time JVM restart request: {}", key);
            }
        }
        // clean old entries
        String basePath = ZkPath.CONTAINER_PROVISION_RESTART.getPath(currentContainerName);
        try {
            if (ZooKeeperUtils.exists(curator, basePath) != null) {
                List<String> zkPaths = ZooKeeperUtils.getAllChildren(curator, ZkPath.CONTAINER_PROVISION_RESTART.getPath(currentContainerName));
                for (String zkPath : zkPaths) {
                    String[] split = zkPath.split("/");
                    String prof = split[split.length - 1];
                    if (!activeProfiles.contains(prof)) {
                        LOGGER.info("Deleting old JVM restart request status: {}", zkPath);
                        ZooKeeperUtils.delete(curator, zkPath);
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("Unable to check ZK connection", e);
        }
        for (String key : jvmRestartEntries.keySet()) {
            String[] split = key.split("\\.");
            String profileForcingRestart = split[split.length - 1];
            try {
                String zkPath = ZkPath.CONTAINER_PROVISION_RESTART_PROFILES.getPath(currentContainerName, profileForcingRestart);
                Stat exists = exists(curator, zkPath);
                if (exists == null) {
                    ZooKeeperUtils.create(curator, zkPath);
                    profilesRequiringRestart.add(profileForcingRestart);
                    result = true;
                }
            } catch (Exception e) {
                LOGGER.error("Unable to check ZK connection", e);
            }
        }
    }
    if (result) {
        System.setProperty("karaf.restart.jvm", "true");
        restart.set(true);
        LOGGER.warn("Profiles {} scheduled a JVM restart request. Automated JVM restart support is not universally available. If your jvm doesn't support it you are required to manually restart the container that has just been assigned the profile.", profilesRequiringRestart);
        try {
            bundleContext.getBundle(0).stop();
        } catch (BundleException e) {
            LOGGER.error("Error when forcing a JVM restart", e);
        }
    }
    return result;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ConfigurationException(org.osgi.service.cm.ConfigurationException) BundleException(org.osgi.framework.BundleException) IOException(java.io.IOException) CuratorFramework(org.apache.curator.framework.CuratorFramework) Stat(org.apache.zookeeper.data.Stat) FabricService(io.fabric8.api.FabricService) BundleException(org.osgi.framework.BundleException)

Example 14 with Agent

use of io.fabric8.agent.service.Agent in project fabric8 by jboss-fuse.

the class DeploymentAgent method doUpdate.

public boolean doUpdate(Dictionary<String, ?> props) throws Exception {
    if (props == null || Boolean.parseBoolean((String) props.get("disabled"))) {
        return false;
    }
    final Hashtable<String, String> properties = new Hashtable<>();
    for (Enumeration e = props.keys(); e.hasMoreElements(); ) {
        Object key = e.nextElement();
        Object val = props.get(key);
        if (!"service.pid".equals(key) && !FeatureConfigInstaller.FABRIC_ZOOKEEPER_PID.equals(key)) {
            properties.put(key.toString(), val.toString());
        }
    }
    updateStatus("analyzing", null);
    // Building configuration
    curatorCompleteService.waitForService(TimeUnit.SECONDS.toMillis(30));
    String httpUrl;
    List<URI> mavenRepoURIs;
    // force reading of updated informations from ZK
    if (!fabricService.isEmpty()) {
        updateMavenRepositoryConfiguration(fabricService.getService());
    }
    try {
        fabricServiceOperations.lock();
        // no one will change the members now
        httpUrl = this.httpUrl;
        mavenRepoURIs = this.mavenRepoURIs;
    } finally {
        fabricServiceOperations.unlock();
    }
    addMavenProxies(properties, httpUrl, mavenRepoURIs);
    final MavenResolver resolver = MavenResolvers.createMavenResolver(properties, "org.ops4j.pax.url.mvn");
    final DownloadManager manager = DownloadManagers.createDownloadManager(resolver, getDownloadExecutor());
    manager.addListener(new DownloadCallback() {

        @Override
        public void downloaded(StreamProvider provider) throws Exception {
            int pending = manager.pending();
            updateStatus(pending > 0 ? "downloading (" + pending + " pending)" : "downloading", null);
        }
    });
    // Update framework, libs, system and config props
    final Object lock = new Object();
    final AtomicBoolean restart = new AtomicBoolean();
    final Set<String> libsToRemove = new HashSet<>(managedLibs.keySet());
    final Set<String> endorsedLibsToRemove = new HashSet<>(managedEndorsedLibs.keySet());
    final Set<String> extensionLibsToRemove = new HashSet<>(managedExtensionLibs.keySet());
    final Set<String> sysPropsToRemove = new HashSet<>(managedSysProps.keySet());
    final Set<String> configPropsToRemove = new HashSet<>(managedConfigProps.keySet());
    final Set<String> etcsToRemove = new HashSet<>(managedEtcs.keySet());
    final Properties configProps = new Properties(new File(KARAF_BASE + File.separator + "etc" + File.separator + "config.properties"));
    final Properties systemProps = new Properties(new File(KARAF_BASE + File.separator + "etc" + File.separator + "system.properties"));
    Downloader downloader = manager.createDownloader();
    for (String key : properties.keySet()) {
        if (key.equals("framework")) {
            String url = properties.get(key);
            if (!url.startsWith("mvn:")) {
                throw new IllegalArgumentException("Framework url must use the mvn: protocol");
            }
            downloader.download(url, new DownloadCallback() {

                @Override
                public void downloaded(StreamProvider provider) throws Exception {
                    File file = provider.getFile();
                    String path = file.getPath();
                    if (path.startsWith(KARAF_HOME)) {
                        path = path.substring(KARAF_HOME.length() + 1);
                    }
                    synchronized (lock) {
                        if (!path.equals(configProps.get("karaf.framework.felix"))) {
                            configProps.put("karaf.framework", "felix");
                            configProps.put("karaf.framework.felix", path);
                            restart.set(true);
                        }
                    }
                }
            });
        } else if (key.startsWith("config.")) {
            String k = key.substring("config.".length());
            String v = properties.get(key);
            synchronized (lock) {
                managedConfigProps.put(k, v);
                configPropsToRemove.remove(k);
                if (!v.equals(configProps.get(k))) {
                    configProps.put(k, v);
                    restart.set(true);
                }
            }
        } else if (key.startsWith("system.")) {
            String k = key.substring("system.".length());
            synchronized (lock) {
                String v = properties.get(key);
                managedSysProps.put(k, v);
                sysPropsToRemove.remove(k);
                if (!v.equals(systemProps.get(k))) {
                    systemProps.put(k, v);
                    restart.set(true);
                }
            }
        } else if (key.startsWith("lib.")) {
            String value = properties.get(key);
            downloader.download(value, new DownloadCallback() {

                @Override
                public void downloaded(StreamProvider provider) throws Exception {
                    File libFile = provider.getFile();
                    String libName = libFile.getName();
                    Long checksum = ChecksumUtils.checksum(libFile);
                    boolean update;
                    synchronized (lock) {
                        managedLibs.put(libName, "true");
                        libsToRemove.remove(libName);
                        update = !Long.toString(checksum).equals(libChecksums.getProperty(libName));
                    }
                    if (update) {
                        Files.copy(libFile, new File(LIB_PATH, libName));
                        restart.set(true);
                    }
                }
            });
        } else if (key.startsWith("endorsed.")) {
            String value = properties.get(key);
            downloader.download(value, new DownloadCallback() {

                @Override
                public void downloaded(StreamProvider provider) throws Exception {
                    File libFile = provider.getFile();
                    String libName = libFile.getName();
                    Long checksum = ChecksumUtils.checksum(new FileInputStream(libFile));
                    boolean update;
                    synchronized (lock) {
                        managedEndorsedLibs.put(libName, "true");
                        endorsedLibsToRemove.remove(libName);
                        update = !Long.toString(checksum).equals(endorsedChecksums.getProperty(libName));
                    }
                    if (update) {
                        Files.copy(libFile, new File(LIB_ENDORSED_PATH, libName));
                        restart.set(true);
                    }
                }
            });
        } else if (key.startsWith("extension.")) {
            String value = properties.get(key);
            downloader.download(value, new DownloadCallback() {

                @Override
                public void downloaded(StreamProvider provider) throws Exception {
                    File libFile = provider.getFile();
                    String libName = libFile.getName();
                    Long checksum = ChecksumUtils.checksum(libFile);
                    boolean update;
                    synchronized (lock) {
                        managedExtensionLibs.put(libName, "true");
                        extensionLibsToRemove.remove(libName);
                        update = !Long.toString(checksum).equals(extensionChecksums.getProperty(libName));
                    }
                    if (update) {
                        Files.copy(libFile, new File(LIB_EXT_PATH, libName));
                        restart.set(true);
                    }
                }
            });
        } else if (key.startsWith("etc.")) {
            String value = properties.get(key);
            downloader.download(value, new DownloadCallback() {

                @Override
                public void downloaded(StreamProvider provider) throws Exception {
                    File etcFile = provider.getFile();
                    String etcName = etcFile.getName();
                    Long checksum = ChecksumUtils.checksum(new FileInputStream(etcFile));
                    boolean update;
                    synchronized (lock) {
                        managedEtcs.put(etcName, "true");
                        etcsToRemove.remove(etcName);
                        update = !Long.toString(checksum).equals(etcChecksums.getProperty(etcName));
                    }
                    if (update) {
                        Files.copy(etcFile, new File(KARAF_ETC, etcName));
                    }
                }
            });
        }
    }
    downloader.await();
    // Remove unused libs, system & config properties
    for (String sysProp : sysPropsToRemove) {
        systemProps.remove(sysProp);
        managedSysProps.remove(sysProp);
        System.clearProperty(sysProp);
        restart.set(true);
    }
    for (String configProp : configPropsToRemove) {
        configProps.remove(configProp);
        managedConfigProps.remove(configProp);
        restart.set(true);
    }
    for (String lib : libsToRemove) {
        File libFile = new File(LIB_PATH, lib);
        libFile.delete();
        libChecksums.remove(lib);
        managedLibs.remove(lib);
        restart.set(true);
    }
    for (String lib : endorsedLibsToRemove) {
        File libFile = new File(LIB_ENDORSED_PATH, lib);
        libFile.delete();
        endorsedChecksums.remove(lib);
        managedEndorsedLibs.remove(lib);
        restart.set(true);
    }
    for (String lib : extensionLibsToRemove) {
        File libFile = new File(LIB_EXT_PATH, lib);
        libFile.delete();
        extensionChecksums.remove(lib);
        managedExtensionLibs.remove(lib);
        restart.set(true);
    }
    for (String etc : etcsToRemove) {
        File etcFile = new File(KARAF_ETC, etc);
        etcFile.delete();
        etcChecksums.remove(etc);
        managedEtcs.remove(etc);
    }
    libChecksums.save();
    endorsedChecksums.save();
    extensionChecksums.save();
    etcChecksums.save();
    managedLibs.save();
    managedEndorsedLibs.save();
    managedExtensionLibs.save();
    managedConfigProps.save();
    managedSysProps.save();
    managedEtcs.save();
    if (restart.get()) {
        updateStatus("restarting", null);
        configProps.save();
        systemProps.save();
        System.setProperty("karaf.restart", "true");
        bundleContext.getBundle(0).stop();
        return false;
    }
    FeatureConfigInstaller configInstaller = null;
    ServiceReference configAdminServiceReference = bundleContext.getServiceReference(ConfigurationAdmin.class.getName());
    if (configAdminServiceReference != null) {
        ConfigurationAdmin configAdmin = (ConfigurationAdmin) bundleContext.getService(configAdminServiceReference);
        configInstaller = new FeatureConfigInstaller(bundleContext, configAdmin, manager);
    }
    int bundleStartTimeout = Constants.BUNDLE_START_TIMEOUT;
    String overriddenTimeout = properties.get(Constants.BUNDLE_START_TIMEOUT_PID_KEY);
    try {
        if (overriddenTimeout != null)
            bundleStartTimeout = Integer.parseInt(overriddenTimeout);
    } catch (Exception e) {
        LOGGER.warn("Failed to set {} value: [{}], applying default value: {}", Constants.BUNDLE_START_TIMEOUT_PID_KEY, overriddenTimeout, Constants.BUNDLE_START_TIMEOUT);
    }
    Agent agent = new Agent(bundleContext.getBundle(), systemBundleContext, manager, configInstaller, null, DEFAULT_FEATURE_RESOLUTION_RANGE, DEFAULT_BUNDLE_UPDATE_RANGE, DEFAULT_UPDATE_SNAPSHOTS, bundleContext.getDataFile(STATE_FILE), bundleStartTimeout) {

        @Override
        public void updateStatus(String status) {
            DeploymentAgent.this.updateStatus(status, null, false);
        }

        @Override
        public void updateStatus(String status, boolean force) {
            DeploymentAgent.this.updateStatus(status, null, force);
        }

        @Override
        protected void saveState(State newState) throws IOException {
            super.saveState(newState);
            DeploymentAgent.this.state.replace(newState);
        }

        @Override
        protected void provisionList(Set<Resource> resources) {
            DeploymentAgent.this.provisionList = resources;
        }

        @Override
        protected boolean done(boolean agentStarted, List<String> urls) {
            if (agentStarted) {
                // let's do patch-management "last touch" only if new agent wasn't started.
                return true;
            }
            // agent finished provisioning, we can call back to low level patch management
            ServiceReference<PatchManagement> srPm = systemBundleContext.getServiceReference(PatchManagement.class);
            ServiceReference<FabricService> srFs = systemBundleContext.getServiceReference(FabricService.class);
            if (srPm != null && srFs != null) {
                PatchManagement pm = systemBundleContext.getService(srPm);
                FabricService fs = systemBundleContext.getService(srFs);
                if (pm != null && fs != null) {
                    LOGGER.info("Validating baseline information");
                    this.updateStatus("validating baseline information", true);
                    Profile profile = fs.getCurrentContainer().getOverlayProfile();
                    Map<String, String> versions = profile.getConfiguration("io.fabric8.version");
                    File localRepository = resolver.getLocalRepository();
                    if (pm.alignTo(versions, urls, localRepository, new PatchSynchronization())) {
                        this.updateStatus("requires full restart", true);
                        // let's reuse the same flag
                        restart.set(true);
                        return false;
                    }
                    if (handleRestartJvmFlag(profile, restart)) {
                        return false;
                    }
                }
            }
            return true;
        }
    };
    agent.setDeploymentAgentId(deploymentAgentId);
    agent.provision(getPrefixedProperties(properties, "repository."), getPrefixedProperties(properties, "feature."), getPrefixedProperties(properties, "bundle."), getPrefixedProperties(properties, "req."), getPrefixedProperties(properties, "override."), getPrefixedProperties(properties, "optional."), getMetadata(properties, "metadata#"));
    if (restart.get()) {
        // prevent updating status to "success"
        return false;
    }
    return true;
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) DownloadCallback(io.fabric8.agent.download.DownloadCallback) Downloader(io.fabric8.agent.download.Downloader) Properties(org.apache.felix.utils.properties.Properties) URI(java.net.URI) DownloadManager(io.fabric8.agent.download.DownloadManager) Profile(io.fabric8.api.Profile) PatchManagement(io.fabric8.patch.management.PatchManagement) MavenResolver(io.fabric8.maven.MavenResolver) List(java.util.List) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Agent(io.fabric8.agent.service.Agent) StreamProvider(io.fabric8.agent.download.StreamProvider) Enumeration(java.util.Enumeration) Hashtable(java.util.Hashtable) ConfigurationException(org.osgi.service.cm.ConfigurationException) BundleException(org.osgi.framework.BundleException) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) ServiceReference(org.osgi.framework.ServiceReference) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) FeatureConfigInstaller(io.fabric8.agent.service.FeatureConfigInstaller) State(io.fabric8.agent.service.State) FabricService(io.fabric8.api.FabricService) File(java.io.File) ConfigurationAdmin(org.osgi.service.cm.ConfigurationAdmin)

Example 15 with Agent

use of io.fabric8.agent.service.Agent in project fabric8 by jboss-fuse.

the class VerifyFeatureResolutionMojo method verifyResolution.

private void verifyResolution(DownloadManager manager, Map<String, Feature> allFeatures, String feature, Hashtable<String, String> properties) throws MojoExecutionException {
    try {
        properties.put("feature.totest", feature);
        FakeSystemBundle systemBundle = getSystemBundleResource(getMetadata(properties, "metadata#"));
        FakeServiceReference profileHandlerSR = new FakeServiceReference(URLStreamHandlerService.class.getName(), "(url.handler.protocol=profile2)");
        systemBundle.setServiceReferences(URLStreamHandlerService.class.getName(), null, new ServiceReference[] { profileHandlerSR });
        systemBundle.setService(profileHandlerSR, new Object());
        Agent agent = new Agent(null, systemBundle, manager);
        agent.setOptions(EnumSet.of(io.fabric8.agent.service.Constants.Option.Simulate, io.fabric8.agent.service.Constants.Option.Silent));
        try {
            agent.provision(allFeatures, getPrefixedProperties(properties, "feature."), getPrefixedProperties(properties, "bundle."), getPrefixedProperties(properties, "req."), getPrefixedProperties(properties, "override."), getPrefixedProperties(properties, "optional."), getMetadata(properties, "metadata#"));
        } catch (Exception e) {
            Set<String> resources = new TreeSet<>(manager.getProviders().keySet());
            throw new MojoExecutionException("Feature resolution failed for " + feature + "\nMessage: " + e.toString() + "\nResources: " + toString(resources), e);
        }
    } catch (MojoExecutionException e) {
        throw e;
    } catch (Exception e) {
        throw new MojoExecutionException("Error verifying feature " + feature + "\nMessage: " + e.getMessage(), e);
    }
}
Also used : Agent(io.fabric8.agent.service.Agent) EnumSet(java.util.EnumSet) Set(java.util.Set) TreeSet(java.util.TreeSet) URLStreamHandlerService(org.osgi.service.url.URLStreamHandlerService) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) IOException(java.io.IOException) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) MojoFailureException(org.apache.maven.plugin.MojoFailureException) MultiException(io.fabric8.common.util.MultiException)

Aggregations

IOException (java.io.IOException)8 FabricService (io.fabric8.api.FabricService)7 Container (io.fabric8.api.Container)6 ArrayList (java.util.ArrayList)6 HashMap (java.util.HashMap)6 Map (java.util.Map)6 Test (org.junit.Test)6 Bundle (org.osgi.framework.Bundle)5 BundleContext (org.osgi.framework.BundleContext)5 Profile (io.fabric8.api.Profile)4 File (java.io.File)4 BundleException (org.osgi.framework.BundleException)4 MultiException (io.fabric8.common.util.MultiException)3 FileInputStream (java.io.FileInputStream)3 List (java.util.List)3 Set (java.util.Set)3 ConfigurationException (org.osgi.service.cm.ConfigurationException)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 DownloadManager (io.fabric8.agent.download.DownloadManager)2 Downloader (io.fabric8.agent.download.Downloader)2