karaf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jean-Baptiste Onofré ...@nanthrax.net>
Subject Re: karaf git commit: [KARAF-4973] Refactoring of features extension
Date Tue, 09 May 2017 08:21:21 GMT
+1

@Christian: can you revert quickly ? Thanks !

Regards
JB

On 05/09/2017 10:14 AM, Guillaume Nodet wrote:
> The feature is completely broken as the {{BundleWires#wiring}} map is never
> modified.
> Please revert and try with a again correct fix ;-)
>
> 2017-02-06 16:00 GMT+01:00 <cschneider@apache.org>:
>
>> Repository: karaf
>> Updated Branches:
>>   refs/heads/master d2f944057 -> 9ce324f57
>>
>>
>> [KARAF-4973] Refactoring of features extension
>>
>>
>> Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
>> Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/9ce324f5
>> Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/9ce324f5
>> Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/9ce324f5
>>
>> Branch: refs/heads/master
>> Commit: 9ce324f577d427d501558740b440f264eb6e2d27
>> Parents: d2f9440
>> Author: Christian Schneider <chris@die-schneider.net>
>> Authored: Wed Feb 1 15:07:42 2017 +0100
>> Committer: Christian Schneider <chris@die-schneider.net>
>> Committed: Mon Feb 6 15:44:34 2017 +0100
>>
>> ----------------------------------------------------------------------
>>  .../karaf/features/extension/Activator.java     | 214 +++----------------
>>  .../karaf/features/extension/BundleWires.java   | 140 ++++++++++++
>>  .../extension/StoredWiringResolver.java         | 112 ++++++++++
>>  3 files changed, 284 insertions(+), 182 deletions(-)
>> ----------------------------------------------------------------------
>>
>>
>> http://git-wip-us.apache.org/repos/asf/karaf/blob/9ce324f5/
>> features/extension/src/main/java/org/apache/karaf/
>> features/extension/Activator.java
>> ----------------------------------------------------------------------
>> diff --git a/features/extension/src/main/java/org/apache/karaf/
>> features/extension/Activator.java b/features/extension/src/main/
>> java/org/apache/karaf/features/extension/Activator.java
>> index f0be0e8..19e2769 100644
>> --- a/features/extension/src/main/java/org/apache/karaf/
>> features/extension/Activator.java
>> +++ b/features/extension/src/main/java/org/apache/karaf/
>> features/extension/Activator.java
>> @@ -16,35 +16,25 @@
>>   */
>>  package org.apache.karaf.features.extension;
>>
>> -import org.osgi.framework.*;
>> -import org.osgi.framework.hooks.resolver.ResolverHook;
>> -import org.osgi.framework.hooks.resolver.ResolverHookFactory;
>> -import org.osgi.framework.namespace.HostNamespace;
>> -import org.osgi.framework.namespace.IdentityNamespace;
>> -import org.osgi.framework.wiring.*;
>> -import org.osgi.resource.Capability;
>> -import org.osgi.resource.Namespace;
>> -import org.osgi.resource.Requirement;
>> -import org.osgi.resource.Resource;
>> -
>> -import java.io.*;
>> -import java.nio.file.Files;
>> -import java.nio.file.Path;
>> -import java.nio.file.StandardOpenOption;
>> -import java.util.*;
>> -import java.util.stream.Collectors;
>> +import java.util.Arrays;
>>
>> -public class Activator implements BundleActivator, ResolverHook,
>> SynchronousBundleListener, ResolverHookFactory {
>> +import org.osgi.framework.BundleActivator;
>> +import org.osgi.framework.BundleContext;
>> +import org.osgi.framework.BundleEvent;
>> +import org.osgi.framework.ServiceRegistration;
>> +import org.osgi.framework.SynchronousBundleListener;
>> +import org.osgi.framework.hooks.resolver.ResolverHookFactory;
>> +import org.osgi.framework.wiring.FrameworkWiring;
>>
>> +public class Activator implements BundleActivator,
>> SynchronousBundleListener {
>>      private static final String WIRING_PATH = "wiring";
>> -
>> -    private final Map<Long, Map<String, String>> wiring = new HashMap<>();
>> -    private BundleContext bundleContext;
>> +       private StoredWiringResolver resolver;
>> +       private BundleContext context;
>>
>>      @Override
>>      public void start(BundleContext context) throws Exception {
>> -        this.bundleContext = context;
>> -        load();
>> +       this.context = context;
>> +        resolver = new StoredWiringResolver(context.
>> getDataFile(WIRING_PATH).toPath());
>>          context.addBundleListener(this);
>>      }
>>
>> @@ -53,163 +43,23 @@ public class Activator implements BundleActivator,
>> ResolverHook, SynchronousBund
>>          context.removeBundleListener(this);
>>      }
>>
>> -    @Override
>> -    public void bundleChanged(BundleEvent event) {
>> -        if (event.getBundle().getBundleId() == 0 && event.getType() ==
>> BundleEvent.STARTED) {
>> -            ServiceRegistration<ResolverHookFactory> registration =
>> bundleContext.registerService(ResolverHookFactory.class, this, null);
>> -            try {
>> -                List<Bundle> bundles = wiring.keySet().stream()
>> -                        .map(id -> bundleContext.getBundle(id))
>> -                        .collect(Collectors.toList());
>> -                bundleContext.getBundle().adapt(FrameworkWiring.class)
>> -                        .resolveBundles(bundles);
>> -            } finally {
>> -                registration.unregister();
>> -            }
>> -        } else if (event.getType() == BundleEvent.RESOLVED ||
>> event.getType() == BundleEvent.UNRESOLVED) {
>> -            synchronized (wiring) {
>> -                long id = event.getBundle().getBundleId();
>> -                if (event.getType() == BundleEvent.RESOLVED) {
>> -                    Map<String, String> bw = new HashMap<>();
>> -                    for (BundleWire wire : event.getBundle().adapt(
>> BundleWiring.class).getRequiredWires(null)) {
>> -                        bw.put(getRequirementId(wire.getRequirement()),
>> getCapabilityId(wire.getCapability()));
>> -                    }
>> -                    wiring.put(id, bw);
>> -                    saveWiring(id, bw);
>> -                } else {
>> -                    wiring.remove(id);
>> -                    saveWiring(id, null);
>> -                }
>> -            }
>> -        }
>> -    }
>> -
>> -    @Override
>> -    public void filterResolvable(Collection<BundleRevision> candidates) {
>> -    }
>> -
>> -    @Override
>> -    public void filterSingletonCollisions(BundleCapability singleton,
>> Collection<BundleCapability> collisionCandidates) {
>> -    }
>> -
>> -    @Override
>> -    public void filterMatches(BundleRequirement requirement,
>> Collection<BundleCapability> candidates) {
>> -        long sourceId = requirement.getRevision().
>> getBundle().getBundleId();
>> -        if (isFragment(requirement.getRevision())
>> -                && !requirement.getNamespace().equals(HostNamespace.HOST_NAMESPACE))
>> {
>> -            sourceId = wiring.get(sourceId).entrySet().stream()
>> -                    .filter(e -> e.getKey().startsWith(
>> HostNamespace.HOST_NAMESPACE))
>> -                    .map(Map.Entry::getValue)
>> -                    .mapToLong(s -> {
>> -                        int idx = s.indexOf(';');
>> -                        if (idx > 0) {
>> -                            s = s.substring(0, idx);
>> -                        }
>> -                        return Long.parseLong(s.trim());
>> -                    })
>> -                    .findFirst()
>> -                    .orElse(-1);
>> -        }
>> -        Map<String, String> bw = wiring.get(sourceId);
>> -        String cap = bw.get(getRequirementId(requirement));
>> -        for (Iterator<BundleCapability> candIter = candidates.iterator();
>> candIter.hasNext();) {
>> -            BundleCapability cand = candIter.next();
>> -            if (cap != null && !cap.equals(getCapabilityId(cand))
>> -                    || cap == null && cand.getRevision().getBundle().getBundleId()
>> != sourceId) {
>> -                candIter.remove();
>> -            }
>> -        }
>> -    }
>> -
>> -    @Override
>> -    public void end() {
>> -    }
>> -
>> -    @Override
>> -    public ResolverHook begin(Collection<BundleRevision> triggers) {
>> -        return this;
>> -    }
>> -
>> -    private void load() {
>> -        try {
>> -            Path dir = bundleContext.getDataFile(WIRING_PATH).toPath();
>> -            Files.createDirectories(dir);
>> -            Files.list(dir).forEach(p -> {
>> -                String name = p.getFileName().toString();
>> -                if (name.matches("[0-9]+")) {
>> -                    try (BufferedReader reader =
>> Files.newBufferedReader(p)) {
>> -                        long id = Long.parseLong(name);
>> -                        Map<String, String> map = new HashMap<>();
>> -                        while (true) {
>> -                            String key = reader.readLine();
>> -                            String val = reader.readLine();
>> -                            if (key != null && val != null) {
>> -                                map.put(key, val);
>> -                            } else {
>> -                                break;
>> -                            }
>> -                        }
>> -                        wiring.put(id, map);
>> -                    } catch (IOException e) {
>> -                        throw new UncheckedIOException(e);
>> -                    }
>> -                }
>> -            });
>> -        } catch (IOException e) {
>> -            throw new UncheckedIOException(e);
>> -        }
>> -    }
>> -
>> -    private void saveWiring(long id, Map<String, String> wiring) {
>> -        try {
>> -            Path dir = bundleContext.getDataFile(WIRING_PATH).toPath();
>> -            Files.createDirectories(dir);
>> -            Path file = dir.resolve(Long.toString(id));
>> -            if (wiring != null) {
>> -                Files.createDirectories(file.getParent());
>> -                try (BufferedWriter fw = Files.newBufferedWriter(file,
>> -                        StandardOpenOption.TRUNCATE_EXISTING,
>> -                        StandardOpenOption.WRITE,
>> -                        StandardOpenOption.CREATE)) {
>> -                    for (Map.Entry<String, String> wire :
>> wiring.entrySet()) {
>> -                        fw.append(wire.getKey()).append('\n');
>> -                        fw.append(wire.getValue()).append('\n');
>> -                    }
>> -                }
>> -            } else {
>> -                Files.deleteIfExists(file);
>> -            }
>> -        } catch (IOException e) {
>> -            throw new UncheckedIOException(e);
>> -        }
>> -    }
>> -
>> -    private String getRequirementId(Requirement requirement) {
>> -        String filter = requirement.getDirectives().
>> get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
>> -        if (filter != null) {
>> -            return requirement.getNamespace() + "; " + filter;
>> -        } else {
>> -            return requirement.getNamespace();
>> -        }
>> -    }
>> -
>> -    private String getCapabilityId(BundleCapability capability) {
>> -        StringBuilder sb = new StringBuilder(64);
>> -        sb.append(capability.getRevision().getBundle().getBundleId());
>> -        Object v = capability.getAttributes().get(Constants.VERSION_
>> ATTRIBUTE);
>> -        if (v != null) {
>> -            sb.append("; version=").append(v.toString());
>> -        }
>> -        return sb.toString();
>> -    }
>> -
>> -    private static boolean isFragment(Resource resource) {
>> -        for (Capability cap : resource.getCapabilities(null)) {
>> -            if (IdentityNamespace.IDENTITY_NAMESPACE.equals(cap.getNamespace()))
>> {
>> -                return IdentityNamespace.TYPE_FRAGMENT.equals(
>> -                        cap.getAttributes().get(
>> IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
>> -            }
>> -        }
>> -        return false;
>> -    }
>> +       @Override
>> +       public void bundleChanged(BundleEvent event) {
>> +               if (event.getBundle().getBundleId() == 0 &&
>> event.getType() == BundleEvent.STARTED) {
>> +                       resolveAll();
>> +               } else if (event.getType() == BundleEvent.RESOLVED) {
>> +                       resolver.update(event.getBundle());
>> +               } else if (event.getType() == BundleEvent.UNRESOLVED) {
>> +                       resolver.delete(event.getBundle());
>> +               }
>> +       }
>> +
>> +       private void resolveAll() {
>> +               ServiceRegistration<ResolverHookFactory> registration =
>> context.registerService(ResolverHookFactory.class, (triggers) ->
>> resolver, null);
>> +               try {
>> +                   context.getBundle().adapt(FrameworkWiring.class).
>> resolveBundles(Arrays.asList(context.getBundles()));
>> +               } finally {
>> +                   registration.unregister();
>> +               }
>> +       }
>>  }
>>
>> http://git-wip-us.apache.org/repos/asf/karaf/blob/9ce324f5/
>> features/extension/src/main/java/org/apache/karaf/features/extension/
>> BundleWires.java
>> ----------------------------------------------------------------------
>> diff --git a/features/extension/src/main/java/org/apache/karaf/
>> features/extension/BundleWires.java b/features/extension/src/main/
>> java/org/apache/karaf/features/extension/BundleWires.java
>> new file mode 100644
>> index 0000000..48b289a
>> --- /dev/null
>> +++ b/features/extension/src/main/java/org/apache/karaf/
>> features/extension/BundleWires.java
>> @@ -0,0 +1,140 @@
>> +/*
>> + * 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.karaf.features.extension;
>> +
>> +import static java.nio.file.StandardOpenOption.CREATE;
>> +import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
>> +import static java.nio.file.StandardOpenOption.WRITE;
>> +
>> +import java.io.BufferedReader;
>> +import java.io.BufferedWriter;
>> +import java.io.IOException;
>> +import java.io.UncheckedIOException;
>> +import java.nio.file.Files;
>> +import java.nio.file.Path;
>> +import java.util.Collection;
>> +import java.util.HashMap;
>> +import java.util.Iterator;
>> +import java.util.Map;
>> +
>> +import org.osgi.framework.Bundle;
>> +import org.osgi.framework.Constants;
>> +import org.osgi.framework.namespace.HostNamespace;
>> +import org.osgi.framework.wiring.BundleCapability;
>> +import org.osgi.framework.wiring.BundleRequirement;
>> +import org.osgi.framework.wiring.BundleWire;
>> +import org.osgi.framework.wiring.BundleWiring;
>> +import org.osgi.resource.Namespace;
>> +import org.osgi.resource.Requirement;
>> +
>> +class BundleWires {
>> +       long bundleId;
>> +       Map<String, String> wiring;
>> +
>> +       BundleWires(Bundle bundle) {
>> +               this.bundleId = bundle.getBundleId();
>> +               this.wiring = new HashMap<>();
>> +        Map<String, String> bw = new HashMap<>();
>> +        for (BundleWire wire : bundle.adapt(BundleWiring.class).getRequiredWires(null))
>> {
>> +            bw.put(getRequirementId(wire.getRequirement()),
>> getCapabilityId(wire.getCapability()));
>> +        }
>> +       }
>> +
>> +       BundleWires(BufferedReader reader) throws IOException {
>> +               Map<String, String> map = new HashMap<>();
>> +               while (true) {
>> +                       String key = reader.readLine();
>> +                       String val = reader.readLine();
>> +                       if (key != null && val != null) {
>> +                               map.put(key, val);
>> +                       } else {
>> +                               break;
>> +                       }
>> +               }
>> +       }
>> +
>> +       void save(Path path) {
>> +               try {
>> +                       Files.createDirectories(path);
>> +                       Path file = path.resolve(Long.toString(
>> this.bundleId));
>> +                       Files.createDirectories(file.getParent());
>> +                       try (BufferedWriter fw =
>> Files.newBufferedWriter(file, TRUNCATE_EXISTING, WRITE, CREATE)) {
>> +                               for (Map.Entry<String, String> wire :
>> wiring.entrySet()) {
>> +                                       fw.append(wire.getKey()).
>> append('\n');
>> +                                       fw.append(wire.getValue()).
>> append('\n');
>> +                               }
>> +                       }
>> +               } catch (IOException e) {
>> +                       throw new UncheckedIOException(e);
>> +               }
>> +       }
>> +
>> +       void delete(Path path) {
>> +               try {
>> +                       Files.createDirectories(path);
>> +                       Path file = path.resolve(Long.toString(
>> this.bundleId));
>> +                       Files.deleteIfExists(file);
>> +               } catch (IOException e) {
>> +                       throw new UncheckedIOException(e);
>> +               }
>> +       }
>> +
>> +       long getFragmentHost() {
>> +               return wiring.entrySet().stream()
>> +        .filter(e -> e.getKey().startsWith(HostNamespace.HOST_NAMESPACE))
>> +        .map(Map.Entry::getValue)
>> +        .mapToLong(s -> {
>> +            int idx = s.indexOf(';');
>> +            if (idx > 0) {
>> +                s = s.substring(0, idx);
>> +            }
>> +            return Long.parseLong(s.trim());
>> +        })
>> +        .findFirst()
>> +        .orElse(-1);
>> +       }
>> +
>> +       void filterMatches(BundleRequirement requirement,
>> Collection<BundleCapability> candidates) {
>> +        String cap = wiring.get(getRequirementId(requirement));
>> +        for (Iterator<BundleCapability> candIter = candidates.iterator();
>> candIter.hasNext();) {
>> +            BundleCapability cand = candIter.next();
>> +            if (cap != null && !cap.equals(getCapabilityId(cand))
>> +                       || cap == null && cand.getRevision().getBundle().getBundleId()
>> != this.bundleId) {
>> +                candIter.remove();
>> +            }
>> +        }
>> +       }
>> +
>> +       private String getRequirementId(Requirement requirement) {
>> +        String filter = requirement.getDirectives().
>> get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
>> +        if (filter != null) {
>> +            return requirement.getNamespace() + "; " + filter;
>> +        } else {
>> +            return requirement.getNamespace();
>> +        }
>> +    }
>> +
>> +    private String getCapabilityId(BundleCapability capability) {
>> +        StringBuilder sb = new StringBuilder(64);
>> +        sb.append(capability.getRevision().getBundle().getBundleId());
>> +        Object v = capability.getAttributes().get(Constants.VERSION_
>> ATTRIBUTE);
>> +        if (v != null) {
>> +            sb.append("; version=").append(v.toString());
>> +        }
>> +        return sb.toString();
>> +    }
>> +}
>>
>> http://git-wip-us.apache.org/repos/asf/karaf/blob/9ce324f5/
>> features/extension/src/main/java/org/apache/karaf/features/extension/
>> StoredWiringResolver.java
>> ----------------------------------------------------------------------
>> diff --git a/features/extension/src/main/java/org/apache/karaf/
>> features/extension/StoredWiringResolver.java
>> b/features/extension/src/main/java/org/apache/karaf/features/extension/
>> StoredWiringResolver.java
>> new file mode 100644
>> index 0000000..3ebd8b4
>> --- /dev/null
>> +++ b/features/extension/src/main/java/org/apache/karaf/
>> features/extension/StoredWiringResolver.java
>> @@ -0,0 +1,112 @@
>> +/*
>> + * 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.karaf.features.extension;
>> +
>> +import java.io.BufferedReader;
>> +import java.io.IOException;
>> +import java.io.UncheckedIOException;
>> +import java.nio.file.Files;
>> +import java.nio.file.Path;
>> +import java.util.Collection;
>> +import java.util.HashMap;
>> +import java.util.Map;
>> +
>> +import org.osgi.framework.Bundle;
>> +import org.osgi.framework.hooks.resolver.ResolverHook;
>> +import org.osgi.framework.namespace.HostNamespace;
>> +import org.osgi.framework.namespace.IdentityNamespace;
>> +import org.osgi.framework.wiring.BundleCapability;
>> +import org.osgi.framework.wiring.BundleRequirement;
>> +import org.osgi.framework.wiring.BundleRevision;
>> +import org.osgi.resource.Capability;
>> +import org.osgi.resource.Resource;
>> +
>> +class StoredWiringResolver implements ResolverHook {
>> +    private final Map<Long, BundleWires> wiring = new HashMap<>();
>> +       private Path path;
>> +
>> +    StoredWiringResolver(Path path) {
>> +       this.path = path;
>> +       load();
>> +       }
>> +
>> +       void load() {
>> +        try {
>> +            Files.createDirectories(path);
>> +            Files.list(path).forEach(p -> {
>> +                String name = p.getFileName().toString();
>> +                if (name.matches("[0-9]+")) {
>> +                    try (BufferedReader reader =
>> Files.newBufferedReader(p)) {
>> +                       long id = Long.parseLong(name);
>> +                        wiring.put(id, new BundleWires(reader));
>> +                    } catch (IOException e) {
>> +                        throw new UncheckedIOException(e);
>> +                    }
>> +                }
>> +            });
>> +        } catch (IOException e) {
>> +            throw new UncheckedIOException(e);
>> +        }
>> +    }
>> +
>> +    @Override
>> +    public void filterResolvable(Collection<BundleRevision> candidates) {
>> +    }
>> +
>> +    @Override
>> +    public void filterSingletonCollisions(BundleCapability singleton,
>> Collection<BundleCapability> collisionCandidates) {
>> +    }
>> +
>> +    @Override
>> +    public void filterMatches(BundleRequirement requirement,
>> Collection<BundleCapability> candidates) {
>> +        long sourceId = getBundleId(requirement);
>> +        wiring.get(sourceId).filterMatches(requirement, candidates);
>> +    }
>> +
>> +    @Override
>> +    public void end() {
>> +    }
>> +
>> +       private long getBundleId(BundleRequirement requirement) {
>> +               long sourceId = requirement.getRevision().
>> getBundle().getBundleId();
>> +        if (isFragment(requirement.getRevision())
>> +                && !requirement.getNamespace().equals(HostNamespace.HOST_NAMESPACE))
>> {
>> +            sourceId = wiring.get(sourceId).getFragmentHost();
>> +        }
>> +               return sourceId;
>> +       }
>> +
>> +    private static boolean isFragment(Resource resource) {
>> +        for (Capability cap : resource.getCapabilities(null)) {
>> +            if (IdentityNamespace.IDENTITY_NAMESPACE.equals(cap.getNamespace()))
>> {
>> +                return IdentityNamespace.TYPE_FRAGMENT.equals(
>> +                        cap.getAttributes().get(
>> IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE));
>> +            }
>> +        }
>> +        return false;
>> +    }
>> +
>> +       synchronized void update(Bundle bundle) {
>> +               BundleWires bw = new BundleWires(bundle);
>> +               bw.save(path);
>> +               wiring.put(bundle.getBundleId(), bw);
>> +       }
>> +
>> +       synchronized void delete(Bundle bundle) {
>> +               wiring.get(bundle.getBundleId()).delete(path);
>> +       }
>> +}
>>
>>
>
>

-- 
Jean-Baptiste Onofré
jbonofre@apache.org
http://blog.nanthrax.net
Talend - http://www.talend.com

Mime
View raw message