X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflowplugin%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fopenflow%2Fmd%2Fcore%2Fsal%2Fconvertor%2FConvertorManager.java;fp=openflowplugin%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fopenflow%2Fmd%2Fcore%2Fsal%2Fconvertor%2FConvertorManager.java;h=191b21d241fd20eb6d5652d60f9d2040ae54e35d;hb=7f4b511776bcdeab7d965ec78fc4a6d5b626ef47;hp=cc30512e32dbff4f1693689a4d52cacbcb753c05;hpb=8339b1175433d51ad1ace15ad7084ec91535d169;p=openflowplugin.git diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/ConvertorManager.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/ConvertorManager.java index cc30512e32..191b21d241 100644 --- a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/ConvertorManager.java +++ b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/ConvertorManager.java @@ -8,23 +8,17 @@ package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor; -import java.util.ArrayList; +import com.google.common.annotations.VisibleForTesting; +import java.util.Arrays; import java.util.Collection; -import java.util.List; +import java.util.Collections; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import javax.annotation.Nullable; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.ActionConvertor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.ActionResponseConvertor; +import java.util.stream.Stream; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Convertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.ConvertorData; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flow.FlowConvertor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flow.FlowInstructionResponseConvertor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.flow.FlowStatsResponseConvertor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchResponseConvertor; -import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchV10ResponseConvertor; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,75 +28,54 @@ import org.slf4j.LoggerFactory; */ public class ConvertorManager implements ConvertorExecutor, ConvertorRegistrator { private static final Logger LOG = LoggerFactory.getLogger(ConvertorManager.class); - private static ConvertorManager INSTANCE; - - static { - INSTANCE = new ConvertorManager(); - // All convertors are registered here - INSTANCE.registerConvertor(new TableFeaturesConvertor()); - INSTANCE.registerConvertor(new TableFeaturesResponseConvertor()); - INSTANCE.registerConvertor(new MeterConvertor()); - INSTANCE.registerConvertor(new MeterStatsResponseConvertor()); - INSTANCE.registerConvertor(new MeterConfigStatsResponseConvertor()); - INSTANCE.registerConvertor(new PortConvertor()); - // TODO: Add MatchConvertor - INSTANCE.registerConvertor(new MatchResponseConvertor()); - INSTANCE.registerConvertor(new MatchV10ResponseConvertor()); - INSTANCE.registerConvertor(new ActionConvertor()); - INSTANCE.registerConvertor(new ActionResponseConvertor()); - INSTANCE.registerConvertor(new GroupConvertor()); - INSTANCE.registerConvertor(new GroupDescStatsResponseConvertor()); - INSTANCE.registerConvertor(new GroupStatsResponseConvertor()); - INSTANCE.registerConvertor(new PacketOutConvertor()); - INSTANCE.registerConvertor(new FlowConvertor()); - INSTANCE.registerConvertor(new FlowInstructionResponseConvertor()); - INSTANCE.registerConvertor(new FlowStatsResponseConvertor()); - } - - // Actual convertor keys - private List> convertorKeys = new ArrayList<>(); // Cache, that holds all registered convertors, but they can have multiple keys, // based on instanceof checks in the convert method - private Map, Convertor> convertors = new ConcurrentHashMap<>(); - - private ConvertorManager() { - // Hiding implicit constructor - } + private Map, Convertor>> convertors; /** - * Gets instance of Convertor Manager. - * - * @return the instance + * Create new instance of Convertor Manager + * @param supportedVersions supported versions */ - public static ConvertorManager getInstance() { - return INSTANCE; + public ConvertorManager(final Short... supportedVersions) { + final Stream stream = Arrays.stream(supportedVersions); + + if (supportedVersions.length == 1) { + final Optional versionOptional = stream.findFirst(); + versionOptional.ifPresent(version -> convertors = Collections.singletonMap(version, new ConcurrentHashMap<>())); + } else { + convertors = new ConcurrentHashMap<>(); + stream.forEach(version -> convertors.putIfAbsent(version, new ConcurrentHashMap<>())); + } } @Override - @SuppressWarnings("unchecked") - public void registerConvertor(final Convertor convertor) { - for (final Object typeRaw : convertor.getTypes()) { - final Class type = (Class)typeRaw; - final Convertor result = convertors.get(type); - - if (Objects.isNull(result)) { - convertorKeys.add(type); - convertors.put(type, convertor); - LOG.debug("{} is now converted by {}", type, convertor); - } else { - LOG.warn("Convertor for type {} is already registered", type); + public ConvertorManager registerConvertor(final short version, final Convertor convertor) { + final Map, Convertor> convertorsForVersion = + convertors.get(version); + + if (Objects.nonNull(convertorsForVersion)) { + for (final Class type : convertor.getTypes()) { + final Convertor result = convertorsForVersion.get(type); + + if (Objects.isNull(result)) { + convertor.setConvertorExecutor(this); + convertorsForVersion.put(type, convertor); + LOG.debug("{} for version {} is now converted by {}", type, version, convertor); + } else { + LOG.warn("{} for version {} have already registered convertor", type, version); + } } + } else { + LOG.warn("{} do not supports version {}", this, version); } - } - public Optional convert(final FROM source) { - return convert(source, null); + return this; } @Override @SuppressWarnings("unchecked") - public Optional convert(final FROM source, @Nullable final DATA data) { + public Optional convert(final FROM source, final DATA data) { Optional result = Optional.empty(); if (Objects.isNull(source)) { @@ -113,26 +86,17 @@ public class ConvertorManager implements ConvertorExecutor, ConvertorRegistrator final Class type = source.getImplementedInterface(); if (Objects.isNull(type)) { - LOG.warn("Cannot extract type from source, because getImplementedInterface() returns null"); + LOG.warn("Cannot extract type from {}, because getImplementedInterface() returns null", source); return result; } - final Optional convertor = findConvertor(type); - - if (convertor.isPresent()) { - result = Optional.of((TO) convertor.get().convert(source, data)); - } - - return result; - } - - public Optional convert(final Collection source) { - return convert(source, null); + return findConvertor(data.getVersion(), type) + .map(convertor -> (TO)convertor.convert(source, data)); } @Override @SuppressWarnings("unchecked") - public Optional convert(final Collection source, @Nullable final DATA data) { + public Optional convert(final Collection source, final DATA data) { Optional result = Optional.empty(); if (Objects.isNull(source)) { @@ -150,17 +114,12 @@ public class ConvertorManager implements ConvertorExecutor, ConvertorRegistrator final Class type = first.get().getImplementedInterface(); if (Objects.isNull(type)) { - LOG.warn("Cannot extract type from source, because getImplementedInterface() returns null"); + LOG.warn("Cannot extract type from {}, because getImplementedInterface() returns null", source); return result; } - final Optional convertor = findConvertor(type); - - if (convertor.isPresent()) { - result = Optional.of((TO) convertor.get().convert(source, data)); - } - - return result; + return findConvertor(data.getVersion(), type) + .map(convertor -> (TO)convertor.convert(source, data)); } /** @@ -170,23 +129,36 @@ public class ConvertorManager implements ConvertorExecutor, ConvertorRegistrator * @param type input type * @return found convertor */ - private Optional findConvertor(final Class type) { - Optional convertor = Optional.ofNullable(convertors.get(type)); - - if (!convertor.isPresent()) { - for (final Class key : convertorKeys) { - if (key.isAssignableFrom(type)) { - final Convertor foundConvertor = convertors.get(key); - convertor = Optional.ofNullable(foundConvertor); - convertors.put(type, foundConvertor); - LOG.warn("{} is now converted by {} using last resort method", type, foundConvertor); - break; - } - } + @VisibleForTesting + Optional findConvertor(final short version, final Class type) { + final Map, Convertor> convertorsForVersion = + convertors.get(version); + + Optional convertor = Optional.empty(); + + if (Objects.nonNull(convertorsForVersion)) { + convertor = Optional.ofNullable(convertorsForVersion.get(type)); if (!convertor.isPresent()) { - LOG.warn("Convertor for {} not found", type); + for (final Class convertorType : convertorsForVersion.keySet()) { + if (type.isAssignableFrom(convertorType)) { + final Convertor foundConvertor = convertorsForVersion.get(convertorType); + convertor = Optional.ofNullable(foundConvertor); + + if (convertor.isPresent()) { + convertorsForVersion.put(type, foundConvertor); + LOG.warn("{} for version {} is now converted by {} using last resort method", type, version, foundConvertor); + break; + } + } + } + + if (!convertor.isPresent()) { + LOG.warn("Convertor for {} for version {} not found", type, version); + } } + } else { + LOG.warn("{} do not supports version {}", this, version); } return convertor;