}
grouping flow-table-and-statistics-map {
- status deprecated;
- description "RPC calls to fetch flow table statistics.";
+ description "List of flow table and statistic map.";
list flow-table-and-statistics-map {
key "table-id";
//Notification for node connector statistics update
grouping node-connector-statistics-and-port-number-map {
- status deprecated;
-
description "List of map - node connectors and their statistics";
list node-connector-statistics-and-port-number-map {
key "node-connector-id";
//RPC calls to fetch queue statistics
grouping queue-id-and-statistics-map {
- status deprecated;
-
list queue-id-and-statistics-map {
key "queue-id node-connector-id";
leaf queue-id {
import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SalRoleService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.SetRoleOutput;
import org.opendaylight.yangtools.yang.common.RpcResult;
MessageSpy getMessageSpy();
- MultiMsgCollector getMultiMsgCollector(final RequestContext<List<MultipartReply>> requestContext);
+ <T extends OfHeader> MultiMsgCollector<T> getMultiMsgCollector(final RequestContext<List<T>> requestContext);
/**
* indicates that device context is fully published (e.g.: packetIn messages should be passed)
*/
ListenableFuture<RpcResult<SetRoleOutput>> makeDeviceSlave();
- boolean isUseSingleLayerSerialization();
+ boolean canUseSingleLayerSerialization();
}
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
/**
* Method that set future to context in Map
*
- * @param xid,
- * @param ofHeaderList
+ * @param xid xid
+ * @param ofHeaderList openflow header list
*/
- void processReply(Xid xid, List<MultipartReply> ofHeaderList);
+ void processReply(Xid xid, List<? extends OfHeader> ofHeaderList);
/**
* Method process async flow removed from device
*
- * @param flowRemoved
+ * @param flowRemoved flow removed
*/
void processFlowRemovedMessage(FlowRemoved flowRemoved);
/**
* Method process async port status from device
*
- * @param portStatus
+ * @param portStatus port status
*/
void processPortStatusMessage(PortStatusMessage portStatus);
/**
* Method process async packet in from device
*
- * @param packetInMessage
+ * @param packetInMessage packet in message
*/
void processPacketInMessage(PacketInMessage packetInMessage);
/**
* Processing of experimenter symmetric message from device
*
- * @param notification
+ * @param notification notification
*/
void processExperimenterMessage(ExperimenterMessage notification);
}
package org.opendaylight.openflowplugin.api.openflow.device.handlers;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
/**
* <p>
* </p>
* Created: Mar 23, 2015
*/
-public interface MultiMsgCollector {
+public interface MultiMsgCollector<T extends OfHeader> {
/**
* Method adds a reply multipart message to the collection and if the message has marker
* "I'M A LAST" method set whole Collection to Future object and remove from cache.
*
- * @param reply
+ * @param reply reply
+ * @param reqMore request more replies
+ * @param eventIdentifier event identifier
*/
- void addMultipartMsg(@Nonnull MultipartReply reply);
-
- void addMultipartMsg(@Nonnull MultipartReply reply, @Nonnull EventIdentifier eventIdentifier);
+ void addMultipartMsg(@Nonnull T reply, boolean reqMore, @Nullable EventIdentifier eventIdentifier);
/**
* Null response could be a valid end multipart collecting event for barrier response scenario.
* We are not able to resolve an issue (it is or it isn't barrier scenario) so we have to finish
* collecting multipart messages successfully.
+ *
+ * @param eventIdentifier event identifier
*/
- void endCollecting();
-
- void endCollecting(EventIdentifier eventIdentifier);
+ void endCollecting(@Nullable EventIdentifier eventIdentifier);
}
package org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
-import java.util.concurrent.Future;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.common.RpcResult;
-/**
- * Created by mirehak on 6/2/15.
- */
-public interface StatisticsGatherer {
- Future<RpcResult<List<MultipartReply>>> getStatisticsOfType(EventIdentifier eventIdentifier, MultipartType type);
+public interface StatisticsGatherer<T extends OfHeader> {
+ ListenableFuture<RpcResult<List<T>>> getStatisticsOfType(EventIdentifier eventIdentifier, MultipartType type);
}
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterManager;
import org.opendaylight.openflowplugin.impl.connection.ConnectionManagerImpl;
import org.opendaylight.openflowplugin.impl.device.DeviceManagerImpl;
+import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProvider;
+import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProviderFactory;
import org.opendaylight.openflowplugin.impl.protocol.deserialization.DeserializerInjector;
import org.opendaylight.openflowplugin.impl.protocol.serialization.SerializerInjector;
import org.opendaylight.openflowplugin.impl.rpc.RpcManagerImpl;
private long basicTimerDelay;
private long maximumTimerDelay;
private boolean useSingleLayerSerialization = false;
+ private final DeviceInitializerProvider deviceInitializerProvider;
private final ThreadPoolExecutor threadPool;
private ClusterSingletonServiceProvider singletonServicesProvider;
Preconditions.checkNotNull(threadPoolMaxThreads),
Preconditions.checkNotNull(threadPoolTimeout), TimeUnit.SECONDS,
new SynchronousQueue<>(), "ofppool");
+
convertorManager = ConvertorManagerFactory.createDefaultManager();
+ deviceInitializerProvider = DeviceInitializerProviderFactory.createDefaultProvider();
}
@Override
hashedWheelTimer,
convertorManager,
skipTableFeatures,
- useSingleLayerSerialization);
+ useSingleLayerSerialization,
+ deviceInitializerProvider);
((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager);
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.statistics;
+
+package org.opendaylight.openflowplugin.impl.common;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
+import java.util.stream.Collectors;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
+import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
+import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
import org.opendaylight.openflowplugin.impl.util.GroupUtil;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdateBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart.reply.body.MultipartReplyDescBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStatsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMapBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.multipart.reply.multipart.reply.body.MultipartReplyFlowTableStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.multipart.reply.multipart.reply.body.MultipartReplyFlowTableStatsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDesc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDescBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.multipart.reply.port.desc.PortsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdatedBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdatedBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupDescBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStatsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdatedBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterFeaturesUpdatedBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStatsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart.reply.body.MultipartReplyPortStatsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStatsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableId;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Class converts multipart reply messages to the notification objects defined
- * by statistics provider (manager ). It is ment to be replaced by translators
- * and to be used for translating statistics data only.
- *
- * @author avishnoi@in.ibm.com
+ * Class converts multipart reply messages to the objects that can be then written to datastore using
+ * multipart writers
*/
-@Deprecated
-public class SinglePurposeMultipartReplyTranslator {
-
- protected static final Logger logger = LoggerFactory
- .getLogger(SinglePurposeMultipartReplyTranslator.class);
- private final ConvertorExecutor convertorExecutor;
+public class MultipartReplyTranslatorUtil {
+ private static final Logger LOG = LoggerFactory.getLogger(MultipartReplyTranslatorUtil.class);
+
+ public static Optional<? extends MultipartReplyBody> translate(final OfHeader message,
+ final DeviceInfo deviceInfo,
+ @Nullable final ConvertorExecutor convertorExecutor,
+ @Nullable final TranslatorLibrary translatorLibrary) {
+ if (message instanceof MultipartReply) {
+ final Optional<ConvertorExecutor> convertor = Optional.ofNullable(convertorExecutor);
+ final Optional<TranslatorLibrary> translator = Optional.ofNullable(translatorLibrary);
+ final MultipartReply msg = MultipartReply.class.cast(message);
+ final OpenflowVersion ofVersion = OpenflowVersion.get(deviceInfo.getVersion());
+ final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(deviceInfo.getVersion());
+ data.setDatapathId(deviceInfo.getDatapathId());
+
+ switch (msg.getType()) {
+ case OFPMPFLOW:
+ return convertor.flatMap(c -> Optional.of(translateFlow(msg, data, c)));
+ case OFPMPAGGREGATE:
+ return Optional.of(translateAggregate(msg));
+ case OFPMPPORTSTATS:
+ return Optional.of(translatePortStats(msg, ofVersion, deviceInfo.getDatapathId()));
+ case OFPMPGROUP:
+ return convertor.flatMap(c -> Optional.of(translateGroup(msg, data, c)));
+ case OFPMPGROUPDESC:
+ return convertor.flatMap(c -> Optional.of(translateGroupDesc(msg, data, c)));
+ case OFPMPGROUPFEATURES:
+ return Optional.of(translateGroupFeatures(msg));
+ case OFPMPMETER:
+ return convertor.flatMap(c -> Optional.of(translateMeter(msg, data, c)));
+ case OFPMPMETERCONFIG:
+ return convertor.flatMap(c -> Optional.of(translateMeterConfig(msg, data, c)));
+ case OFPMPMETERFEATURES:
+ return Optional.of(translateMeterFeatures(msg));
+ case OFPMPTABLE:
+ return Optional.of(translateTable(msg));
+ case OFPMPQUEUE:
+ return Optional.of(translateQueue(msg, ofVersion, deviceInfo.getDatapathId()));
+ case OFPMPDESC:
+ return Optional.of(translateDesc(msg));
+ case OFPMPTABLEFEATURES:
+ return convertor.flatMap(c -> Optional.of(translateTableFeatures(msg, deviceInfo.getVersion(), c)));
+ case OFPMPPORTDESC:
+ return translator.flatMap(t -> Optional.of(translatePortDesc(msg, deviceInfo, t)));
+ }
+ } else if (message instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
+ .MultipartReply) {
+ return Optional.of(org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112
+ .MultipartReply.class.cast(message).getMultipartReplyBody());
+ }
- public SinglePurposeMultipartReplyTranslator(ConvertorExecutor convertorExecutor) {
- this.convertorExecutor = convertorExecutor;
+ LOG.debug("Failed to translate {} for node {}.", message.getImplementedInterface(), deviceInfo.getLOGValue());
+ return Optional.empty();
}
- public List<DataObject> translate(final BigInteger datapathId, final short version, final OfHeader msg) {
-
- List<DataObject> listDataObject = new ArrayList<>();
-
- if (msg instanceof MultipartReplyMessage) {
- MultipartReplyMessage mpReply = (MultipartReplyMessage) msg;
- OpenflowVersion ofVersion = OpenflowVersion.get(version);
- NodeId node = nodeIdFromDatapathId(datapathId);
- VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(version);
- data.setDatapathId(datapathId);
-
- translateFlow(listDataObject, mpReply, node, data);
- translateAggregate(listDataObject, mpReply, node);
- translatePortStats(listDataObject, mpReply, node, ofVersion, datapathId);
- translateGroup(listDataObject, mpReply, node, data);
- translateGroupDesc(listDataObject, mpReply, node, data);
- translateGroupFeatures(listDataObject, mpReply, node);
- translateMeter(listDataObject, mpReply, node, data);
- translateMeterConfig(listDataObject, mpReply, node, data);
- translateMeterFeatures(listDataObject, mpReply, node);
- translateTable(listDataObject, mpReply, node);
- translateQueue(listDataObject, mpReply, node, ofVersion, datapathId);
- }
+ private static MultipartReplyPortDesc translatePortDesc(final MultipartReply msg,
+ final DeviceInfo deviceInfo,
+ final TranslatorLibrary translatorLibrary) {
+ return new MultipartReplyPortDescBuilder()
+ .setPorts(((MultipartReplyPortDescCase) msg.getMultipartReplyBody())
+ .getMultipartReplyPortDesc()
+ .getPorts()
+ .stream()
+ .map(port -> {
+ final TranslatorKey translatorKey = new TranslatorKey(
+ deviceInfo.getVersion(),
+ PortGrouping.class.getName());
+
+ final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = translatorLibrary
+ .lookupTranslator(translatorKey);
+
+ return new PortsBuilder(translator
+ .translate(port, deviceInfo, null))
+ .build();
+ })
+ .collect(Collectors.toList()))
+ .build();
+ }
- return listDataObject;
+ private static org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.multipart.reply.multipart.reply.body
+ .MultipartReplyTableFeatures translateTableFeatures(final MultipartReply msg,
+ final short version,
+ final ConvertorExecutor convertorExecutor) {
+ MultipartReplyTableFeaturesCase caseBody = (MultipartReplyTableFeaturesCase) msg.getMultipartReplyBody();
+ final MultipartReplyTableFeatures multipartReplyTableFeatures = caseBody.getMultipartReplyTableFeatures();
+ final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features
+ .TableFeatures>> tableFeaturesList = convertorExecutor
+ .convert(multipartReplyTableFeatures, new VersionConvertorData(version));
+
+ return new MultipartReplyTableFeaturesBuilder()
+ .setTableFeatures(tableFeaturesList.orElse(Collections.emptyList()))
+ .build();
}
- private void translateFlow(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node, VersionDatapathIdConvertorData data) {
- if (!MultipartType.OFPMPFLOW.equals(mpReply.getType())) {
- return;
- }
+ private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.multipart.reply.multipart.reply.body
+ .MultipartReplyDesc translateDesc(final MultipartReply msg) {
+ final MultipartReplyDesc desc = ((MultipartReplyDescCase) msg.getMultipartReplyBody()).getMultipartReplyDesc();
+
+ return new MultipartReplyDescBuilder()
+ .setDescription(desc.getDpDesc())
+ .setHardware(desc.getHwDesc())
+ .setManufacturer(desc.getMfrDesc())
+ .setSoftware(desc.getSwDesc())
+ .setSerialNumber(desc.getSerialNum())
+ .build();
+ }
+ private static MultipartReplyFlowStats translateFlow(final MultipartReply msg,
+ final VersionDatapathIdConvertorData data,
+ final ConvertorExecutor convertorExecutor) {
FlowStatsResponseConvertorData flowData = new FlowStatsResponseConvertorData(data.getVersion());
flowData.setDatapathId(data.getDatapathId());
flowData.setMatchPath(MatchPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_MATCH);
- FlowsStatisticsUpdateBuilder message = new FlowsStatisticsUpdateBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
- MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) mpReply.getMultipartReplyBody();
+ MultipartReplyFlowStatsBuilder message = new MultipartReplyFlowStatsBuilder();
+ MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) msg.getMultipartReplyBody();
MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
final Optional<List<FlowAndStatisticsMapList>> flowAndStatisticsMapLists =
- convertorExecutor.convert(replyBody.getFlowStats(), flowData);
+ convertorExecutor.convert(replyBody.getFlowStats(), flowData);
message.setFlowAndStatisticsMapList(flowAndStatisticsMapLists.orElse(Collections.emptyList()));
-
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateAggregate(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node) {
- if (!MultipartType.OFPMPAGGREGATE.equals(mpReply.getType())) {
- return;
- }
-
- AggregateFlowStatisticsUpdateBuilder message = new AggregateFlowStatisticsUpdateBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
-
- MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase) mpReply.getMultipartReplyBody();
+ private static MultipartReplyFlowAggregateStats translateAggregate(final MultipartReply msg) {
+ MultipartReplyFlowAggregateStatsBuilder message = new MultipartReplyFlowAggregateStatsBuilder();
+ MultipartReplyAggregateCase caseBody = (MultipartReplyAggregateCase) msg.getMultipartReplyBody();
MultipartReplyAggregate replyBody = caseBody.getMultipartReplyAggregate();
message.setByteCount(new Counter64(replyBody.getByteCount()));
message.setPacketCount(new Counter64(replyBody.getPacketCount()));
message.setFlowCount(new Counter32(replyBody.getFlowCount()));
-
- listDataObject.add(message.build());
+ return message.build();
}
- private void translatePortStats(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node,
- final OpenflowVersion ofVersion,
- final BigInteger datapathId) {
- if (!MultipartType.OFPMPPORTSTATS.equals(mpReply.getType())) {
- return;
- }
-
- NodeConnectorStatisticsUpdateBuilder message = new NodeConnectorStatisticsUpdateBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
-
- MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) mpReply.getMultipartReplyBody();
+ private static org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart.reply.body
+ .MultipartReplyPortStats translatePortStats(final MultipartReply msg,
+ final OpenflowVersion ofVersion,
+ final BigInteger datapathId) {
+ MultipartReplyPortStatsBuilder message = new MultipartReplyPortStatsBuilder();
+ MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) msg.getMultipartReplyBody();
MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
List<NodeConnectorStatisticsAndPortNumberMap> statsMap =
- new ArrayList<>();
+ new ArrayList<>();
for (PortStats portStats : replyBody.getPortStats()) {
NodeConnectorStatisticsAndPortNumberMapBuilder statsBuilder =
- new NodeConnectorStatisticsAndPortNumberMapBuilder();
+ new NodeConnectorStatisticsAndPortNumberMapBuilder();
statsBuilder.setNodeConnectorId(
- InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
- portStats.getPortNo(), ofVersion));
+ InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
+ portStats.getPortNo(), ofVersion));
BytesBuilder bytesBuilder = new BytesBuilder();
bytesBuilder.setReceived(portStats.getRxBytes());
message.setNodeConnectorStatisticsAndPortNumberMap(statsMap);
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateGroup(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node,
- final VersionDatapathIdConvertorData data) {
- if (!MultipartType.OFPMPGROUP.equals(mpReply.getType())) {
- return;
- }
-
- GroupStatisticsUpdatedBuilder message = new GroupStatisticsUpdatedBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
- MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) mpReply.getMultipartReplyBody();
+ private static MultipartReplyGroupStats translateGroup(final MultipartReply msg,
+ final VersionDatapathIdConvertorData data,
+ final ConvertorExecutor convertorExecutor) {
+ MultipartReplyGroupStatsBuilder message = new MultipartReplyGroupStatsBuilder();
+ MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) msg.getMultipartReplyBody();
MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
final Optional<List<GroupStats>> groupStatsList = convertorExecutor.convert(
- replyBody.getGroupStats(), data);
+ replyBody.getGroupStats(), data);
message.setGroupStats(groupStatsList.orElse(Collections.emptyList()));
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateGroupDesc(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node,
- final VersionDatapathIdConvertorData data) {
- if (!MultipartType.OFPMPGROUPDESC.equals(mpReply.getType())) {
- return;
- }
-
- GroupDescStatsUpdatedBuilder message = new GroupDescStatsUpdatedBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
- MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) mpReply.getMultipartReplyBody();
+ private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body
+ .MultipartReplyGroupDesc translateGroupDesc(final MultipartReply msg,
+ final VersionDatapathIdConvertorData data,
+ final ConvertorExecutor convertorExecutor) {
+ MultipartReplyGroupDescBuilder message = new MultipartReplyGroupDescBuilder();
+ MultipartReplyGroupDescCase caseBody = (MultipartReplyGroupDescCase) msg.getMultipartReplyBody();
MultipartReplyGroupDesc replyBody = caseBody.getMultipartReplyGroupDesc();
final Optional<List<GroupDescStats>> groupDescStatsList = convertorExecutor.convert(
- replyBody.getGroupDesc(), data);
+ replyBody.getGroupDesc(), data);
message.setGroupDescStats(groupDescStatsList.orElse(Collections.emptyList()));
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateGroupFeatures(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node) {
- if (!MultipartType.OFPMPGROUPFEATURES.equals(mpReply.getType())) {
- return;
- }
-
- GroupFeaturesUpdatedBuilder message = new GroupFeaturesUpdatedBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
- MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase) mpReply.getMultipartReplyBody();
+ private static org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body
+ .MultipartReplyGroupFeatures translateGroupFeatures(final MultipartReply msg) {
+ MultipartReplyGroupFeaturesBuilder message = new MultipartReplyGroupFeaturesBuilder();
+ MultipartReplyGroupFeaturesCase caseBody = (MultipartReplyGroupFeaturesCase) msg.getMultipartReplyBody();
MultipartReplyGroupFeatures replyBody = caseBody.getMultipartReplyGroupFeatures();
List<Class<? extends GroupType>> supportedGroups =
- new ArrayList<>();
+ new ArrayList<>();
if (replyBody.getTypes().isOFPGTALL()) {
supportedGroups.add(GroupAll.class);
message.setMaxGroups(replyBody.getMaxGroups());
List<Class<? extends GroupCapability>> supportedCapabilities =
- new ArrayList<>();
+ new ArrayList<>();
if (replyBody.getCapabilities().isOFPGFCCHAINING()) {
supportedCapabilities.add(Chaining.class);
message.setGroupCapabilitiesSupported(supportedCapabilities);
message.setActions(GroupUtil.extractGroupActionsSupportBitmap(replyBody.getActionsBitmap()));
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateMeter(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node,
- final VersionDatapathIdConvertorData data) {
- if (!MultipartType.OFPMPMETER.equals(mpReply.getType())) {
- return;
- }
-
- MeterStatisticsUpdatedBuilder message = new MeterStatisticsUpdatedBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
-
- MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) mpReply.getMultipartReplyBody();
+ private static MultipartReplyMeterStats translateMeter(final MultipartReply msg,
+ final VersionDatapathIdConvertorData data,
+ final ConvertorExecutor convertorExecutor) {
+ MultipartReplyMeterStatsBuilder message = new MultipartReplyMeterStatsBuilder();
+ MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) msg.getMultipartReplyBody();
MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats>> meterStatsList =
- convertorExecutor.convert(replyBody.getMeterStats(), data);
+ convertorExecutor.convert(replyBody.getMeterStats(), data);
message.setMeterStats(meterStatsList.orElse(Collections.emptyList()));
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateMeterConfig(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node,
- final VersionDatapathIdConvertorData data) {
- if (!MultipartType.OFPMPMETERCONFIG.equals(mpReply.getType())) {
- return;
- }
-
- MeterConfigStatsUpdatedBuilder message = new MeterConfigStatsUpdatedBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
-
- MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) mpReply.getMultipartReplyBody();
+ private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body
+ .MultipartReplyMeterConfig translateMeterConfig(final MultipartReply msg,
+ final VersionDatapathIdConvertorData data,
+ final ConvertorExecutor convertorExecutor) {
+ MultipartReplyMeterConfigBuilder message = new MultipartReplyMeterConfigBuilder();
+ MultipartReplyMeterConfigCase caseBody = (MultipartReplyMeterConfigCase) msg.getMultipartReplyBody();
MultipartReplyMeterConfig replyBody = caseBody.getMultipartReplyMeterConfig();
final Optional<List<MeterConfigStats>> meterConfigStatsList = convertorExecutor.convert(replyBody.getMeterConfig(), data);
message.setMeterConfigStats(meterConfigStatsList.orElse(Collections.emptyList()));
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateMeterFeatures(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node) {
- if (!MultipartType.OFPMPMETERFEATURES.equals(mpReply.getType())) {
- return;
- }
-
- //Convert OF message and send it to SAL listener
- MeterFeaturesUpdatedBuilder message = new MeterFeaturesUpdatedBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
-
- MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) mpReply.getMultipartReplyBody();
+ private static org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body
+ .MultipartReplyMeterFeatures translateMeterFeatures(final MultipartReply msg) {
+ MultipartReplyMeterFeaturesBuilder message = new MultipartReplyMeterFeaturesBuilder();
+ MultipartReplyMeterFeaturesCase caseBody = (MultipartReplyMeterFeaturesCase) msg.getMultipartReplyBody();
MultipartReplyMeterFeatures replyBody = caseBody.getMultipartReplyMeterFeatures();
message.setMaxBands(replyBody.getMaxBands());
message.setMaxColor(replyBody.getMaxColor());
message.setMaxMeter(new Counter32(replyBody.getMaxMeter()));
List<Class<? extends MeterCapability>> supportedCapabilities =
- new ArrayList<>();
+ new ArrayList<>();
if (replyBody.getCapabilities().isOFPMFBURST()) {
supportedCapabilities.add(MeterBurst.class);
}
message.setMeterCapabilitiesSupported(supportedCapabilities);
List<Class<? extends MeterBand>> supportedMeterBand =
- new ArrayList<>();
+ new ArrayList<>();
if (replyBody.getBandTypes().isOFPMBTDROP()) {
supportedMeterBand.add(MeterBandDrop.class);
}
supportedMeterBand.add(MeterBandDscpRemark.class);
}
message.setMeterBandSupported(supportedMeterBand);
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateTable(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node) {
- if (!MultipartType.OFPMPTABLE.equals(mpReply.getType())) {
- return;
- }
-
- FlowTableStatisticsUpdateBuilder message = new FlowTableStatisticsUpdateBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
-
- MultipartReplyTableCase caseBody = (MultipartReplyTableCase) mpReply.getMultipartReplyBody();
+ private static MultipartReplyFlowTableStats translateTable(final MultipartReply msg) {
+ MultipartReplyFlowTableStatsBuilder message = new MultipartReplyFlowTableStatsBuilder();
+ MultipartReplyTableCase caseBody = (MultipartReplyTableCase) msg.getMultipartReplyBody();
MultipartReplyTable replyBody = caseBody.getMultipartReplyTable();
List<TableStats> swTablesStats = replyBody.getTableStats();
}
message.setFlowTableAndStatisticsMap(salFlowStats);
- listDataObject.add(message.build());
+ return message.build();
}
- private void translateQueue(final List<DataObject> listDataObject,
- final MultipartReplyMessage mpReply,
- final NodeId node,
- final OpenflowVersion ofVersion,
- final BigInteger datapathId) {
- if (!MultipartType.OFPMPQUEUE.equals(mpReply.getType())) {
- return;
- }
-
- QueueStatisticsUpdateBuilder message = new QueueStatisticsUpdateBuilder();
- message.setId(node);
- message.setMoreReplies(mpReply.getFlags().isOFPMPFREQMORE());
- message.setTransactionId(generateTransactionId(mpReply.getXid()));
-
- MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) mpReply.getMultipartReplyBody();
+ private static MultipartReplyQueueStats translateQueue(final MultipartReply msg,
+ final OpenflowVersion ofVersion,
+ final BigInteger datapathId) {
+ MultipartReplyQueueStatsBuilder message = new MultipartReplyQueueStatsBuilder();
+ MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) msg.getMultipartReplyBody();
MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
List<QueueIdAndStatisticsMap> statsMap =
- new ArrayList<QueueIdAndStatisticsMap>();
+ new ArrayList<>();
for (QueueStats queueStats : replyBody.getQueueStats()) {
QueueIdAndStatisticsMapBuilder statsBuilder =
- new QueueIdAndStatisticsMapBuilder();
+ new QueueIdAndStatisticsMapBuilder();
statsBuilder.setNodeConnectorId(
- InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
- queueStats.getPortNo(), ofVersion));
+ InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
+ queueStats.getPortNo(), ofVersion));
statsBuilder.setTransmissionErrors(new Counter64(queueStats.getTxErrors()));
statsBuilder.setTransmittedBytes(new Counter64(queueStats.getTxBytes()));
statsBuilder.setTransmittedPackets(new Counter64(queueStats.getTxPackets()));
statsBuilder.setQueueId(new QueueId(queueStats.getQueueId()));
statsBuilder.setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathId,
- queueStats.getPortNo(), ofVersion));
+ queueStats.getPortNo(), ofVersion));
statsMap.add(statsBuilder.build());
}
message.setQueueIdAndStatisticsMap(statsMap);
- listDataObject.add(message.build());
+ return message.build();
}
- private static NodeId nodeIdFromDatapathId(final BigInteger datapathId) {
- String current = datapathId.toString();
- return new NodeId("openflow:" + current);
- }
-
- private static TransactionId generateTransactionId(final Long xid) {
- BigInteger bigIntXid = BigInteger.valueOf(xid);
- return new TransactionId(bigIntXid);
- }
}
+++ /dev/null
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.common;
-
-import com.google.common.base.Preconditions;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortNumberUni;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.State;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.StateBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortStateV10;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPort;
-
-/**
- * openflowplugin-impl
- * org.opendaylight.openflowplugin.impl.common
- *
- * Translator helper for Translating OF java models to MD-SAL inventory models.
- * Translator focus for {@link NodeConnector} object and relevant OF augmentation
- * {@link FlowCapableNodeConnector}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Mar 31, 2015
- */
-public final class NodeConnectorTranslatorUtil {
-
- private NodeConnectorTranslatorUtil () {
- throw new UnsupportedOperationException("Utility class");
- }
-
- /**
- * Method translates {@link PhyPort} object directly to {@link NodeConnector} which is augmented
- * by {@link FlowCapableNodeConnector} and contains all relevant content translated by actual OF version.
- *
- * @param featuresReply
- * @return
- */
- public static List<NodeConnector> translateNodeConnectorFromFeaturesReply(@CheckForNull final FeaturesReply featuresReply) {
- Preconditions.checkArgument(featuresReply != null);
- Preconditions.checkArgument(featuresReply.getPhyPort() != null);
- final Short version = featuresReply.getVersion();
- final BigInteger dataPathId = featuresReply.getDatapathId();
- final List<NodeConnector> resultList = new ArrayList<>(featuresReply.getPhyPort().size());
- for (final PhyPort port : featuresReply.getPhyPort()) {
- final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder();
- ncBuilder.setId(makeNodeConnectorId(dataPathId, port.getName(), port.getPortNo()));
- ncBuilder.addAugmentation(FlowCapableNodeConnector.class, translateFlowCapableNodeFromPhyPort(port, version));
- resultList.add(ncBuilder.build());
- }
- return resultList;
- }
-
- /**
- * Method translates {@link PhyPort} object directly to {@link FlowCapableNodeConnector} which is augmented
- * by {@link NodeConnector} and contains all relevant content translated by actual OF version.
- *
- * @param port
- * @param version
- * @return
- */
- public static FlowCapableNodeConnector translateFlowCapableNodeFromPhyPort(@CheckForNull final PhyPort port, final short version) {
- Preconditions.checkArgument(port != null);
- final FlowCapableNodeConnectorBuilder fcncBuilder = new FlowCapableNodeConnectorBuilder();
- fcncBuilder.setHardwareAddress(port.getHwAddr());
- fcncBuilder.setCurrentSpeed(port.getCurrSpeed());
- fcncBuilder.setMaximumSpeed(port.getMaxSpeed());
- fcncBuilder.setName(port.getName());
- fcncBuilder.setPortNumber(new PortNumberUni(port.getPortNo()));
- if (OFConstants.OFP_VERSION_1_3 == version) {
- fcncBuilder.setAdvertisedFeatures(translatePortFeatures(port.getAdvertisedFeatures()));
- fcncBuilder.setConfiguration(translatePortConfig(port.getConfig()));
- fcncBuilder.setCurrentFeature(translatePortFeatures(port.getCurrentFeatures()));
- fcncBuilder.setPeerFeatures(translatePortFeatures(port.getPeerFeatures()));
- fcncBuilder.setSupported(translatePortFeatures(port.getSupportedFeatures()));
- fcncBuilder.setState(translatePortState(port.getState()));
- } else if (OFConstants.OFP_VERSION_1_0 == version) {
- fcncBuilder.setAdvertisedFeatures(translatePortFeatures(port.getAdvertisedFeaturesV10()));
- fcncBuilder.setConfiguration(translatePortConfig(port.getConfigV10()));
- fcncBuilder.setCurrentFeature(translatePortFeatures(port.getCurrentFeaturesV10()));
- fcncBuilder.setPeerFeatures(translatePortFeatures(port.getPeerFeaturesV10()));
- fcncBuilder.setSupported(translatePortFeatures(port.getSupportedFeaturesV10()));
- fcncBuilder.setState(translatePortState(port.getStateV10()));
- } else {
- throw new IllegalArgumentException("Unknown OF version " + version);
- }
- return fcncBuilder.build();
- }
-
- private static PortConfig translatePortConfig(@CheckForNull final org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig pc) {
- Preconditions.checkArgument(pc != null);
- return new PortConfig(pc.isNoFwd(), pc.isNoPacketIn(), pc.isNoRecv(), pc.isPortDown());
- }
-
- private static PortConfig translatePortConfig(@CheckForNull final PortConfigV10 pc) {
- Preconditions.checkArgument(pc != null);
- return new PortConfig(pc.isNoFwd(), pc.isNoPacketIn(), pc.isNoRecv(), pc.isPortDown());
- }
-
- private static PortFeatures translatePortFeatures(@CheckForNull final org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures pf) {
- Preconditions.checkArgument(pf != null);
- return new PortFeatures(pf.isAutoneg(), pf.isCopper(), pf.isFiber(), pf.is_40gbFd(), pf.is_100gbFd(), pf.is_100mbFd(), pf.is_100mbHd(),
- pf.is_1gbFd(), pf.is_1gbHd(), pf.is_1tbFd(), pf.isOther(), pf.isPause(), pf.isPauseAsym(), pf.is_10gbFd(), pf.is_10mbFd(), pf.is_10mbHd());
- }
-
- private static PortFeatures translatePortFeatures(@CheckForNull final PortFeaturesV10 pf) {
- Preconditions.checkArgument(pf != null);
- return new PortFeatures(pf.isAutoneg(), pf.isCopper(), pf.isFiber(), Boolean.FALSE, Boolean.FALSE, pf.is_100mbFd(), pf.is_100mbHd(),
- pf.is_1gbFd(), pf.is_1gbHd(), Boolean.FALSE, Boolean.FALSE, pf.isPause(), pf.isPauseAsym(), pf.is_10gbFd(), pf.is_10mbFd(), pf.is_10mbHd());
- }
-
- private static State translatePortState(@CheckForNull final PortState state) {
- Preconditions.checkArgument(state != null);
- return new StateBuilder().setBlocked(state.isBlocked()).setLinkDown(state.isLinkDown()).setLive(state.isLive()).build();
- }
-
- private static State translatePortState(@CheckForNull final PortStateV10 state) {
- Preconditions.checkArgument(state != null);
- return new StateBuilder().setBlocked(state.isBlocked()).setLinkDown(state.isLinkDown()).setLive(state.isLive()).build();
- }
-
- /**
- * Method makes NodeConnectorId with prefix "openflow:" from dataPathId and logical name or port number
- *
- * @param dataPathId
- * @param logicalName
- * @param portNo
- * @return
- */
- public static NodeConnectorId makeNodeConnectorId(@CheckForNull final BigInteger dataPathId,
- @Nullable final String logicalName, final long portNo) {
- Preconditions.checkArgument(dataPathId != null);
- return new NodeConnectorId(OFConstants.OF_URI_PREFIX + dataPathId + ":" + (logicalName == null ? portNo : logicalName));
- }
-}
+++ /dev/null
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.common;
-
-import com.google.common.base.Preconditions;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import javax.annotation.CheckForNull;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.impl.util.GroupUtil;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
-import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.Chaining;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.ChainingChecks;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupAll;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFf;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupIndirect;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupSelect;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectLiveness;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.SelectWeight;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBand;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDrop;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandDscpRemark;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBurst;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterCapability;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterKbps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterPktps;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
-
-/**
- * <p>
- * openflowplugin-impl
- * org.opendaylight.openflowplugin.impl.common
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- * </p>
- * Created: Mar 31, 2015
- */
-public class NodeStaticReplyTranslatorUtil {
-
- private NodeStaticReplyTranslatorUtil() {
- throw new UnsupportedOperationException("Utility class");
- }
-
- /**
- * Method transforms OFjava multipart reply model {@link MultipartReplyDesc} object
- * to inventory data model {@link FlowCapableNode} object.
- *
- * @param reply
- * @return
- */
- public static FlowCapableNodeBuilder nodeDescTranslator(@CheckForNull final MultipartReplyDesc reply, final IpAddress ipAddress) {
- Preconditions.checkArgument(reply != null);
- final FlowCapableNodeBuilder flowCapAugBuilder = new FlowCapableNodeBuilder();
- flowCapAugBuilder.setDescription(reply.getDpDesc());
- flowCapAugBuilder.setHardware(reply.getHwDesc());
- flowCapAugBuilder.setManufacturer(reply.getMfrDesc());
- flowCapAugBuilder.setSoftware(reply.getSwDesc());
- flowCapAugBuilder.setSerialNumber(reply.getSerialNum());
- flowCapAugBuilder.setTable(Collections.<Table>emptyList());
- flowCapAugBuilder.setMeter(Collections.<Meter>emptyList());
- flowCapAugBuilder.setGroup(Collections.<Group>emptyList());
- if (ipAddress != null) {
- flowCapAugBuilder.setIpAddress(ipAddress);
- }
- return flowCapAugBuilder;
- }
-
- /**
- * Method transforms OFjava multipart reply model {@link MultipartReplyMeterFeatures} object
- * to inventory data model {@link NodeMeterFeatures} object.
- *
- * @param reply
- * @return
- */
- public static NodeMeterFeatures nodeMeterFeatureTranslator(@CheckForNull final MultipartReplyMeterFeatures reply) {
- Preconditions.checkArgument(reply != null);
- final MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder();
- meterFeature.setMaxBands(reply.getMaxBands());
- meterFeature.setMaxColor(reply.getMaxColor());
- meterFeature.setMaxMeter(new Counter32(reply.getMaxMeter()));
- final List<Class<? extends MeterBand>> meterBandTypes = new ArrayList<>();
- if (reply.getBandTypes().isOFPMBTDROP()) {
- meterBandTypes.add(MeterBandDrop.class);
- }
- if (reply.getBandTypes().isOFPMBTDSCPREMARK()) {
- meterBandTypes.add(MeterBandDscpRemark.class);
- }
- meterFeature.setMeterBandSupported(Collections.unmodifiableList(meterBandTypes));
-
- final List<java.lang.Class<? extends MeterCapability>> mCapability = new ArrayList<>();
- if (reply.getCapabilities().isOFPMFBURST()) {
- mCapability.add(MeterBurst.class);
- }
- if (reply.getCapabilities().isOFPMFKBPS()) {
- mCapability.add(MeterKbps.class);
-
- }
- if (reply.getCapabilities().isOFPMFPKTPS()) {
- mCapability.add(MeterPktps.class);
-
- }
- if (reply.getCapabilities().isOFPMFSTATS()) {
- mCapability.add(MeterStats.class);
-
- }
- meterFeature.setMeterCapabilitiesSupported(Collections.unmodifiableList(mCapability));
- return new NodeMeterFeaturesBuilder().setMeterFeatures(meterFeature.build()).build();
- }
-
- /**
- * Method transforms OFjava reply model {@link MultipartReplyGroupFeatures} object
- * to inventory data model {@link NodeGroupFeatures} object.
- *
- * @param reply
- * @return
- */
- public static NodeGroupFeatures nodeGroupFeatureTranslator(@CheckForNull final MultipartReplyGroupFeatures reply) {
- Preconditions.checkArgument(reply != null);
- final GroupFeaturesBuilder groupFeature = new GroupFeaturesBuilder();
- groupFeature.setMaxGroups(reply.getMaxGroups());
-
- final List<Class<? extends GroupType>> supportedGroups = new ArrayList<>();
- addSupportedGroups(reply, supportedGroups);
- groupFeature.setGroupTypesSupported(supportedGroups);
-
- final List<Class<? extends GroupCapability>> gCapability = new ArrayList<>();
- addGroupCapabilities(reply, gCapability);
- groupFeature.setGroupCapabilitiesSupported(gCapability);
-
- groupFeature.setActions(GroupUtil.extractGroupActionsSupportBitmap(reply.getActionsBitmap()));
- return new NodeGroupFeaturesBuilder().setGroupFeatures(groupFeature.build()).build();
- }
-
- private static void addGroupCapabilities(final MultipartReplyGroupFeatures reply, final List<Class<? extends GroupCapability>> gCapability) {
- if (reply.getCapabilities().isOFPGFCCHAINING()) {
- gCapability.add(Chaining.class);
- }
- if (reply.getCapabilities().isOFPGFCCHAININGCHECKS()) {
- gCapability.add(ChainingChecks.class);
- }
- if (reply.getCapabilities().isOFPGFCSELECTLIVENESS()) {
- gCapability.add(SelectLiveness.class);
- }
- if (reply.getCapabilities().isOFPGFCSELECTWEIGHT()) {
- gCapability.add(SelectWeight.class);
- }
- }
-
- private static void addSupportedGroups(final MultipartReplyGroupFeatures reply, final List<Class<? extends GroupType>> supportedGroups) {
- if (reply.getTypes().isOFPGTALL()) {
- supportedGroups.add(GroupAll.class);
- }
- if (reply.getTypes().isOFPGTSELECT()) {
- supportedGroups.add(GroupSelect.class);
- }
- if (reply.getTypes().isOFPGTINDIRECT()) {
- supportedGroups.add(GroupIndirect.class);
- }
- if (reply.getTypes().isOFPGTFF()) {
- supportedGroups.add(GroupFf.class);
- }
- }
-
- /**
- * Method transform {@link MultipartReplyTableFeatures} to list of {@link TableFeatures}. Every
- * table can have List of TableFeatures so add it directly to
- * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder}
- *
- * @param reply reply
- * @param version Openflow version
- * @param convertorExecutor convertor executor
- * @return list of table features
- */
- public static List<TableFeatures> nodeTableFeatureTranslator(@CheckForNull final MultipartReplyTableFeatures reply, final short version, @CheckForNull final ConvertorExecutor convertorExecutor) {
- Preconditions.checkArgument(reply != null);
- Preconditions.checkArgument(convertorExecutor != null);
- final Optional<List<TableFeatures>> tableFeaturesList = convertorExecutor.convert(reply, new VersionConvertorData(version));
- return tableFeaturesList.orElse(Collections.emptyList());
- }
-
- /**
- * Method build a ID Node Connector from version and port number.
- *
- * @param datapathId
- * @param portNo
- * @param version
- * @return
- */
- public static NodeConnectorId nodeConnectorId(@CheckForNull final String datapathId, final long portNo, final short version) {
- Preconditions.checkArgument(datapathId != null);
- final String logicalName = OpenflowPortsUtil.getPortLogicalName(version, portNo);
- return new NodeConnectorId(OFConstants.OF_URI_PREFIX + datapathId + ":" + (logicalName == null ? portNo : logicalName));
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.AbstractMultipartWriter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+
+public class MultipartWriterProvider {
+
+ private final Map<MultipartType, AbstractMultipartWriter> writers = new HashMap<>();
+
+ /**
+ * Register statistics writer.
+ *
+ * @param type the writer type
+ * @param writer the writer instance
+ */
+ public void register(final MultipartType type, final AbstractMultipartWriter writer) {
+ writers.put(type, writer);
+ }
+
+ /**
+ * Lookup statistics writer.
+ *
+ * @param type the writer type
+ * @return the writer instance
+ */
+ public Optional<AbstractMultipartWriter> lookup(final MultipartType type) {
+ return Optional.ofNullable(writers.get(type));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.DescMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.FlowStatsMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.GroupDescMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.GroupFeaturesMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.GroupStatsMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.MeterConfigMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.MeterFeaturesMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.MeterStatsMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.PortDescMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.PortStatsMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.QueueStatsMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.TableFeaturesMultipartWriter;
+import org.opendaylight.openflowplugin.impl.datastore.multipart.TableStatsMultipartWriter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Multipart writer provider factory
+ */
+public class MultipartWriterProviderFactory {
+
+ /**
+ * Create default #{@link MultipartWriterProvider}
+ * @param deviceContext device context
+ * @return the statistics writer provider
+ */
+ public static MultipartWriterProvider createDefaultProvider(final DeviceContext deviceContext) {
+ final InstanceIdentifier<Node> instanceIdentifier = deviceContext.getDeviceInfo().getNodeInstanceIdentifier();
+ final MultipartWriterProvider provider = new MultipartWriterProvider();
+
+ // Periodic/direct statistics writers
+ provider.register(MultipartType.OFPMPTABLE, new TableStatsMultipartWriter(deviceContext, instanceIdentifier));
+ provider.register(MultipartType.OFPMPGROUP, new GroupStatsMultipartWriter(deviceContext, instanceIdentifier));
+ provider.register(MultipartType.OFPMPMETER, new MeterStatsMultipartWriter(deviceContext, instanceIdentifier));
+ provider.register(MultipartType.OFPMPPORTSTATS, new PortStatsMultipartWriter(deviceContext, instanceIdentifier, deviceContext.getPrimaryConnectionContext().getFeatures()));
+ provider.register(MultipartType.OFPMPQUEUE, new QueueStatsMultipartWriter(deviceContext, instanceIdentifier));
+ provider.register(MultipartType.OFPMPFLOW, new FlowStatsMultipartWriter(deviceContext, instanceIdentifier, deviceContext, deviceContext.getDeviceInfo().getVersion()));
+ provider.register(MultipartType.OFPMPGROUPDESC, new GroupDescMultipartWriter(deviceContext, instanceIdentifier, deviceContext));
+ provider.register(MultipartType.OFPMPMETERCONFIG, new MeterConfigMultipartWriter(deviceContext, instanceIdentifier, deviceContext));
+
+ // Device initialization writers
+ provider.register(MultipartType.OFPMPDESC, new DescMultipartWriter(deviceContext, instanceIdentifier, deviceContext.getPrimaryConnectionContext()));
+ provider.register(MultipartType.OFPMPGROUPFEATURES, new GroupFeaturesMultipartWriter(deviceContext, instanceIdentifier));
+ provider.register(MultipartType.OFPMPMETERFEATURES, new MeterFeaturesMultipartWriter(deviceContext, instanceIdentifier));
+ provider.register(MultipartType.OFPMPTABLEFEATURES, new TableFeaturesMultipartWriter(deviceContext, instanceIdentifier));
+ provider.register(MultipartType.OFPMPPORTDESC, new PortDescMultipartWriter(deviceContext, instanceIdentifier, deviceContext.getPrimaryConnectionContext().getFeatures()));
+
+ return provider;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractMultipartWriter<T extends DataContainer> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipartService.class);
+
+ private final TxFacade txFacade;
+ private final InstanceIdentifier<Node> instanceIdentifier;
+
+ AbstractMultipartWriter(final TxFacade txFacade, final InstanceIdentifier<Node> instanceIdentifier) {
+ this.txFacade = txFacade;
+ this.instanceIdentifier = instanceIdentifier;
+ }
+
+ /**
+ * Creates put operation using provided data in underlying transaction chain.
+ * @param path path
+ * @param data data
+ * @param <O> data type
+ */
+ protected <O extends DataObject> void writeToTransaction(final InstanceIdentifier<O> path,
+ final O data,
+ final boolean withParents) {
+ if (withParents) {
+ txFacade.writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, path, data);
+ } else {
+ txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, path, data);
+ }
+ }
+
+ /**
+ * Get instance identifier
+ * @return instance identifier
+ */
+ protected InstanceIdentifier<Node> getInstanceIdentifier() {
+ return instanceIdentifier;
+ }
+
+ /**
+ * Write dataContainer
+ * @param dataContainer dataContainer
+ * @param withParents write missing parents if needed (slower)
+ * @return true if we have correct dataContainer type
+ */
+ public boolean write(final DataContainer dataContainer, final boolean withParents) {
+ if (getType().isInstance(dataContainer)) {
+ LOG.debug("Writing multipart data of type {} for node {}", getType(), getInstanceIdentifier());
+ storeStatistics(getType().cast(dataContainer), withParents);
+ return true;
+ }
+
+ LOG.debug("Failed to write multipart data of type {} for node {}", getType(), getInstanceIdentifier());
+ return false;
+ }
+
+ /**
+ * Get type of writer
+ * @return type of writer
+ */
+ protected abstract Class<T> getType();
+
+ /**
+ * Write statistics
+ * @param statistics statistics
+ * @param withParents write missing parents if needed (slower)
+ */
+ protected abstract void storeStatistics(final T statistics,
+ final boolean withParents);
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import java.util.Collections;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Desc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class DescMultipartWriter extends AbstractMultipartWriter<Desc> {
+
+ private final ConnectionContext connectionContext;
+
+ public DescMultipartWriter(final TxFacade txFacade,
+ final InstanceIdentifier<Node> instanceIdentifier,
+ final ConnectionContext connectionContext) {
+ super(txFacade, instanceIdentifier);
+ this.connectionContext = connectionContext;
+ }
+
+ @Override
+ protected Class<Desc> getType() {
+ return Desc.class;
+ }
+
+ @Override
+ public void storeStatistics(final Desc statistics, final boolean withParents) {
+ writeToTransaction(getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class),
+ new FlowCapableNodeBuilder(statistics)
+ .setTable(Collections.emptyList())
+ .setMeter(Collections.emptyList())
+ .setGroup(Collections.emptyList())
+ .setIpAddress(DeviceInitializationUtil.getIpAddress(connectionContext, getInstanceIdentifier()))
+ .setSwitchFeatures(DeviceInitializationUtil.getSwitchFeatures(connectionContext))
+ .build(),
+ withParents);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class FlowStatsMultipartWriter extends AbstractMultipartWriter<FlowAndStatisticsMapList> {
+
+ private final DeviceRegistry registry;
+ private final short version;
+
+ public FlowStatsMultipartWriter(final TxFacade txFacade,
+ final InstanceIdentifier<Node> instanceIdentifier,
+ final DeviceRegistry registry,
+ final short version) {
+ super(txFacade, instanceIdentifier);
+ this.registry = registry;
+ this.version = version;
+ }
+
+ @Override
+ protected Class<FlowAndStatisticsMapList> getType() {
+ return FlowAndStatisticsMapList.class;
+ }
+
+ @Override
+ public void storeStatistics(final FlowAndStatisticsMapList statistics, final boolean withParents) {
+ statistics.getFlowAndStatisticsMapList()
+ .forEach(stat -> {
+ final FlowBuilder flow = new FlowBuilder(stat)
+ .addAugmentation(
+ FlowStatisticsData.class,
+ new FlowStatisticsDataBuilder()
+ .setFlowStatistics(new FlowStatisticsBuilder(stat).build())
+ .build());
+
+ final FlowKey key = new FlowKey(registry
+ .getDeviceFlowRegistry()
+ .storeIfNecessary(FlowRegistryKeyFactory
+ .create(version, flow.build())));
+
+ writeToTransaction(
+ getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(stat.getTableId()))
+ .child(Flow.class, key),
+ flow
+ .setId(key.getId())
+ .setKey(key)
+ .build(),
+ withParents);
+ });
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupDescStatsReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class GroupDescMultipartWriter extends AbstractMultipartWriter<GroupDescStatsReply> {
+
+ private final DeviceRegistry registry;
+
+ public GroupDescMultipartWriter(final TxFacade txFacade,
+ final InstanceIdentifier<Node> instanceIdentifier,
+ final DeviceRegistry registry) {
+ super(txFacade, instanceIdentifier);
+ this.registry = registry;
+ }
+
+ @Override
+ protected Class<GroupDescStatsReply> getType() {
+ return GroupDescStatsReply.class;
+ }
+
+ @Override
+ public void storeStatistics(final GroupDescStatsReply statistics, final boolean withParents) {
+ statistics.getGroupDescStats()
+ .forEach(stat -> {
+ writeToTransaction(
+ getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Group.class, new GroupKey(stat.getGroupId())),
+ new GroupBuilder(stat)
+ .setKey(new GroupKey(stat.getGroupId()))
+ .addAugmentation(NodeGroupStatistics.class, new NodeGroupStatisticsBuilder().build())
+ .build(),
+ withParents);
+
+ registry.getDeviceGroupRegistry().store(stat.getGroupId());
+ });
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class GroupFeaturesMultipartWriter extends AbstractMultipartWriter<GroupFeatures> {
+
+ public GroupFeaturesMultipartWriter(final TxFacade txFacade, final InstanceIdentifier<Node> instanceIdentifier) {
+ super(txFacade, instanceIdentifier);
+ }
+
+ @Override
+ protected Class<GroupFeatures> getType() {
+ return GroupFeatures.class;
+ }
+
+ @Override
+ public void storeStatistics(final GroupFeatures statistics, final boolean withParents) {
+ writeToTransaction(getInstanceIdentifier()
+ .augmentation(NodeGroupFeatures.class),
+ new NodeGroupFeaturesBuilder()
+ .setGroupFeatures(new GroupFeaturesBuilder(statistics)
+ .build())
+ .build(),
+ withParents);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupStatisticsReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class GroupStatsMultipartWriter extends AbstractMultipartWriter<GroupStatisticsReply> {
+
+ public GroupStatsMultipartWriter(final TxFacade txFacade, final InstanceIdentifier<Node> instanceIdentifier) {
+ super(txFacade, instanceIdentifier);
+ }
+
+ @Override
+ protected Class<GroupStatisticsReply> getType() {
+ return GroupStatisticsReply.class;
+ }
+
+ @Override
+ public void storeStatistics(final GroupStatisticsReply statistics, final boolean withParents) {
+ statistics.getGroupStats()
+ .forEach(stat -> writeToTransaction(
+ getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Group.class, new GroupKey(stat.getGroupId()))
+ .augmentation(NodeGroupStatistics.class)
+ .child(GroupStatistics.class),
+ new GroupStatisticsBuilder(stat).build(),
+ withParents));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterConfigStatsReply;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class MeterConfigMultipartWriter extends AbstractMultipartWriter<MeterConfigStatsReply> {
+
+ private final DeviceRegistry registry;
+
+ public MeterConfigMultipartWriter(final TxFacade txFacade,
+ final InstanceIdentifier<Node> instanceIdentifier,
+ final DeviceRegistry registry) {
+ super(txFacade, instanceIdentifier);
+ this.registry = registry;
+ }
+
+ @Override
+ protected Class<MeterConfigStatsReply> getType() {
+ return MeterConfigStatsReply.class;
+ }
+
+ @Override
+ public void storeStatistics(final MeterConfigStatsReply statistics, final boolean withParents) {
+ statistics.getMeterConfigStats()
+ .forEach(stat -> {
+ writeToTransaction(
+ getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Meter.class, new MeterKey(stat.getMeterId())),
+ new MeterBuilder(stat)
+ .setKey(new MeterKey(stat.getMeterId()))
+ .addAugmentation(NodeMeterStatistics.class, new NodeMeterStatisticsBuilder().build())
+ .build(),
+ withParents);
+
+ registry.getDeviceMeterRegistry().store(stat.getMeterId());
+ });
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeatures;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class MeterFeaturesMultipartWriter extends AbstractMultipartWriter<MeterFeatures> {
+
+ public MeterFeaturesMultipartWriter(final TxFacade txFacade, final InstanceIdentifier<Node> instanceIdentifier) {
+ super(txFacade, instanceIdentifier);
+ }
+
+ @Override
+ protected Class<MeterFeatures> getType() {
+ return MeterFeatures.class;
+ }
+
+ @Override
+ public void storeStatistics(final MeterFeatures statistics, final boolean withParents) {
+ writeToTransaction(getInstanceIdentifier()
+ .augmentation(NodeMeterFeatures.class),
+ new NodeMeterFeaturesBuilder()
+ .setMeterFeatures(statistics)
+ .build(),
+ withParents);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterStatisticsReply;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class MeterStatsMultipartWriter extends AbstractMultipartWriter<MeterStatisticsReply> {
+
+ public MeterStatsMultipartWriter(final TxFacade txFacade, final InstanceIdentifier<Node> instanceIdentifier) {
+ super(txFacade, instanceIdentifier);
+ }
+
+ @Override
+ protected Class<MeterStatisticsReply> getType() {
+ return MeterStatisticsReply.class;
+ }
+
+ @Override
+ public void storeStatistics(final MeterStatisticsReply statistics, final boolean withParents) {
+ statistics.getMeterStats()
+ .forEach(stat -> writeToTransaction(
+ getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Meter.class, new MeterKey(stat.getMeterId()))
+ .augmentation(NodeMeterStatistics.class)
+ .child(MeterStatistics.class),
+ new MeterStatisticsBuilder(stat).build(),
+ withParents));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.multipart.reply.multipart.reply.body.MultipartReplyPortDesc;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class PortDescMultipartWriter extends AbstractMultipartWriter<MultipartReplyPortDesc> {
+
+ private final FeaturesReply features;
+
+ public PortDescMultipartWriter(final TxFacade txFacade,
+ final InstanceIdentifier<Node> instanceIdentifier,
+ final FeaturesReply features) {
+ super(txFacade, instanceIdentifier);
+ this.features = features;
+ }
+
+ @Override
+ protected Class<MultipartReplyPortDesc> getType() {
+ return MultipartReplyPortDesc.class;
+ }
+
+ @Override
+ public void storeStatistics(final MultipartReplyPortDesc statistics, final boolean withParents) {
+ statistics.getPorts()
+ .forEach(stat -> {
+ final NodeConnectorId id = InventoryDataServiceUtil
+ .nodeConnectorIdfromDatapathPortNo(
+ features.getDatapathId(),
+ OpenflowPortsUtil.getProtocolPortNumber(
+ OpenflowVersion.get(features.getVersion()),
+ stat.getPortNumber()),
+ OpenflowVersion.get(features.getVersion()));
+
+ writeToTransaction(
+ getInstanceIdentifier()
+ .child(NodeConnector.class, new NodeConnectorKey(id)),
+ new NodeConnectorBuilder()
+ .setId(id)
+ .addAugmentation(
+ FlowCapableNodeConnector.class,
+ new FlowCapableNodeConnectorBuilder(stat).build())
+ .addAugmentation(
+ FlowCapableNodeConnectorStatisticsData.class,
+ new FlowCapableNodeConnectorStatisticsDataBuilder().build())
+ .build(),
+ withParents);
+ });
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsAndPortNumberMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class PortStatsMultipartWriter extends AbstractMultipartWriter<NodeConnectorStatisticsAndPortNumberMap> {
+
+ private final FeaturesReply features;
+
+ public PortStatsMultipartWriter(final TxFacade txFacade,
+ final InstanceIdentifier<Node> instanceIdentifier,
+ final FeaturesReply features) {
+ super(txFacade, instanceIdentifier);
+ this.features = features;
+ }
+
+ @Override
+ protected Class<NodeConnectorStatisticsAndPortNumberMap> getType() {
+ return NodeConnectorStatisticsAndPortNumberMap.class;
+ }
+
+ @Override
+ public void storeStatistics(final NodeConnectorStatisticsAndPortNumberMap statistics, final boolean withParents) {
+ statistics.getNodeConnectorStatisticsAndPortNumberMap()
+ .forEach(stat -> {
+ final OpenflowVersion openflowVersion = OpenflowVersion.get(features.getVersion());
+ final Long port = InventoryDataServiceUtil
+ .portNumberfromNodeConnectorId(openflowVersion, stat.getNodeConnectorId());
+
+ final NodeConnectorId id = InventoryDataServiceUtil
+ .nodeConnectorIdfromDatapathPortNo(
+ features.getDatapathId(),
+ port,
+ OpenflowVersion.get(features.getVersion()));
+
+ writeToTransaction(
+ getInstanceIdentifier()
+ .child(NodeConnector.class, new NodeConnectorKey(id))
+ .augmentation(FlowCapableNodeConnectorStatisticsData.class)
+ .child(FlowCapableNodeConnectorStatistics.class),
+ new FlowCapableNodeConnectorStatisticsBuilder(stat)
+ .build(),
+ withParents);
+ });
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueIdAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class QueueStatsMultipartWriter extends AbstractMultipartWriter<QueueIdAndStatisticsMap> {
+
+ public QueueStatsMultipartWriter(final TxFacade txFacade, final InstanceIdentifier<Node> instanceIdentifier) {
+ super(txFacade, instanceIdentifier);
+ }
+
+ @Override
+ protected Class<QueueIdAndStatisticsMap> getType() {
+ return QueueIdAndStatisticsMap.class;
+ }
+
+ @Override
+ public void storeStatistics(final QueueIdAndStatisticsMap statistics, final boolean withParents) {
+ statistics.getQueueIdAndStatisticsMap()
+ .forEach(stat -> writeToTransaction(
+ getInstanceIdentifier()
+ .child(NodeConnector.class, new NodeConnectorKey(stat.getNodeConnectorId()))
+ .augmentation(FlowCapableNodeConnector.class)
+ .child(Queue.class, new QueueKey(stat.getQueueId())),
+ new QueueBuilder()
+ .setKey(new QueueKey(stat.getQueueId()))
+ .setQueueId(stat.getQueueId())
+ .addAugmentation(
+ FlowCapableNodeConnectorQueueStatisticsData.class,
+ new FlowCapableNodeConnectorQueueStatisticsDataBuilder()
+ .setFlowCapableNodeConnectorQueueStatistics(
+ new FlowCapableNodeConnectorQueueStatisticsBuilder(stat).build())
+ .build())
+ .build(),
+ withParents));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class TableFeaturesMultipartWriter extends AbstractMultipartWriter<TableFeatures> {
+
+ public TableFeaturesMultipartWriter(final TxFacade txFacade,
+ final InstanceIdentifier<Node> instanceIdentifier) {
+ super(txFacade, instanceIdentifier);
+ }
+
+ @Override
+ protected Class<TableFeatures> getType() {
+ return TableFeatures.class;
+ }
+
+ @Override
+ public void storeStatistics(final TableFeatures statistics, final boolean withParents) {
+ statistics.getTableFeatures()
+ .forEach(stat -> {
+ writeToTransaction(getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features
+ .TableFeatures.class,
+ new TableFeaturesKey(stat.getTableId())),
+ stat,
+ withParents);
+
+ // Write parent for table statistics
+ writeToTransaction(getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(stat.getTableId())),
+ new TableBuilder()
+ .setId(stat.getTableId())
+ .addAugmentation(FlowTableStatisticsData.class, new FlowTableStatisticsDataBuilder()
+ .build())
+ .build(),
+ withParents);
+ });
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.datastore.multipart;
+
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class TableStatsMultipartWriter extends AbstractMultipartWriter<FlowTableAndStatisticsMap> {
+
+ public TableStatsMultipartWriter(final TxFacade txFacade, final InstanceIdentifier<Node> instanceIdentifier) {
+ super(txFacade, instanceIdentifier);
+ }
+
+ @Override
+ protected Class<FlowTableAndStatisticsMap> getType() {
+ return FlowTableAndStatisticsMap.class;
+ }
+
+ @Override
+ public void storeStatistics(final FlowTableAndStatisticsMap statistics,
+ final boolean withParents) {
+ statistics.getFlowTableAndStatisticsMap()
+ .forEach(stat -> writeToTransaction(
+ getInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(stat.getTableId().getValue()))
+ .augmentation(FlowTableStatisticsData.class)
+ .child(FlowTableStatistics.class),
+ new FlowTableStatisticsBuilder(stat).build(),
+ withParents));
+ }
+
+}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
+import org.opendaylight.openflowplugin.api.ConnectionException;
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.openflowplugin.api.openflow.registry.ItemLifeCycleRegistry;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
import org.opendaylight.openflowplugin.impl.common.ItemLifeCycleSourceImpl;
-import org.opendaylight.openflowplugin.impl.common.NodeStaticReplyTranslatorUtil;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
+import org.opendaylight.openflowplugin.impl.device.initialization.AbstractDeviceInitializer;
+import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProvider;
import org.opendaylight.openflowplugin.impl.device.listener.MultiMsgCollectorImpl;
import org.opendaylight.openflowplugin.impl.registry.flow.DeviceFlowRegistryImpl;
import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
import org.opendaylight.openflowplugin.impl.registry.group.DeviceGroupRegistryImpl;
import org.opendaylight.openflowplugin.impl.registry.meter.DeviceMeterRegistryImpl;
import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
-import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtils;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.ExperimenterMessageFromDevBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketIn;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
private volatile CONTEXT_STATE state;
private ClusterInitializationPhaseHandler clusterInitializationPhaseHandler;
private final DeviceManager myManager;
+ private final DeviceInitializerProvider deviceInitializerProvider;
private final boolean useSingleLayerSerialization;
DeviceContextImpl(
- @Nonnull final ConnectionContext primaryConnectionContext,
- @Nonnull final DataBroker dataBroker,
- @Nonnull final MessageSpy messageSpy,
- @Nonnull final TranslatorLibrary translatorLibrary,
- @Nonnull final DeviceManager manager,
- final ConvertorExecutor convertorExecutor,
- final boolean skipTableFeatures,
- final HashedWheelTimer hashedWheelTimer,
- final DeviceManager myManager,
- final boolean useSingleLayerSerialization) {
+ @Nonnull final ConnectionContext primaryConnectionContext,
+ @Nonnull final DataBroker dataBroker,
+ @Nonnull final MessageSpy messageSpy,
+ @Nonnull final TranslatorLibrary translatorLibrary,
+ @Nonnull final DeviceManager manager,
+ final ConvertorExecutor convertorExecutor,
+ final boolean skipTableFeatures,
+ final HashedWheelTimer hashedWheelTimer,
+ final DeviceManager myManager,
+ final boolean useSingleLayerSerialization,
+ final DeviceInitializerProvider deviceInitializerProvider) {
+
this.primaryConnectionContext = primaryConnectionContext;
this.deviceInfo = primaryConnectionContext.getDeviceInfo();
this.hashedWheelTimer = hashedWheelTimer;
this.myManager = myManager;
+ this.deviceInitializerProvider = deviceInitializerProvider;
this.deviceState = new DeviceStateImpl();
this.dataBroker = dataBroker;
this.auxiliaryConnectionContexts = new HashMap<>();
@Override
public void processReply(final OfHeader ofHeader) {
- if (ofHeader instanceof Error) {
- messageSpy.spyMessage(ofHeader.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE);
- } else {
- messageSpy.spyMessage(ofHeader.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS);
- }
+ messageSpy.spyMessage(
+ ofHeader.getImplementedInterface(),
+ (ofHeader instanceof Error)
+ ? MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE
+ : MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS);
}
@Override
- public void processReply(final Xid xid, final List<MultipartReply> ofHeaderList) {
- for (final MultipartReply multipartReply : ofHeaderList) {
- messageSpy.spyMessage(multipartReply.getImplementedInterface(), MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE);
- }
+ public void processReply(final Xid xid, final List<? extends OfHeader> ofHeaderList) {
+ ofHeaderList.forEach(header -> messageSpy.spyMessage(
+ header.getImplementedInterface(),
+ (header instanceof Error)
+ ? MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE
+ : MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS));
}
@Override
private KeyedInstanceIdentifier<NodeConnector, NodeConnectorKey> provideIIToNodeConnector(final long portNo, final short version) {
final InstanceIdentifier<Node> iiToNodes = getDeviceInfo().getNodeInstanceIdentifier();
final BigInteger dataPathId = getDeviceInfo().getDatapathId();
- final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId(dataPathId.toString(), portNo, version);
+ final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(dataPathId, portNo, OpenflowVersion.get(version));
return iiToNodes.child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId));
}
}
@Override
- public MultiMsgCollector getMultiMsgCollector(final RequestContext<List<MultipartReply>> requestContext) {
- return new MultiMsgCollectorImpl(this, requestContext);
+ public <T extends OfHeader> MultiMsgCollector<T> getMultiMsgCollector(final RequestContext<List<T>> requestContext) {
+ return new MultiMsgCollectorImpl<>(this, requestContext);
}
@Override
}
@Override
- public boolean isUseSingleLayerSerialization() {
- return useSingleLayerSerialization;
+ public boolean canUseSingleLayerSerialization() {
+ return useSingleLayerSerialization && getDeviceInfo().getVersion() >= OFConstants.OFP_VERSION_1_3;
}
@Override
this.transactionChainManager.activateTransactionManager();
try {
- DeviceInitializationUtils.initializeNodeInformation(this, switchFeaturesMandatory, this.convertorExecutor);
+ final Optional<AbstractDeviceInitializer> initializer = deviceInitializerProvider
+ .lookup(deviceInfo.getVersion());
+
+ if (initializer.isPresent()) {
+ final MultipartWriterProvider writerProvider = MultipartWriterProviderFactory.createDefaultProvider(this);
+ initializer.get().initialize(this, switchFeaturesMandatory, writerProvider, convertorExecutor);
+ } else {
+ throw new ExecutionException(new ConnectionException("Unsupported version " + deviceInfo.getVersion()));
+ }
} catch (ExecutionException | InterruptedException e) {
LOG.warn("Device {} cannot be initialized: ", deviceInfo.getLOGValue(), e);
return false;
}
Futures.addCallback(sendRoleChangeToDevice(OfpRole.BECOMEMASTER), new RpcResultFutureCallback());
-
return this.clusterInitializationPhaseHandler.onContextInstantiateService(getPrimaryConnectionContext());
}
import org.opendaylight.openflowplugin.extension.api.ExtensionConverterProviderKeeper;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
import org.opendaylight.openflowplugin.impl.connection.OutboundQueueProviderImpl;
+import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProvider;
import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl;
import org.opendaylight.openflowplugin.impl.lifecycle.LifecycleServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalRoleServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalRoleServiceImpl;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
private static final int SPY_RATE = 10;
private final DataBroker dataBroker;
+ private final DeviceInitializerProvider deviceInitializerProvider;
private final ConvertorExecutor convertorExecutor;
private TranslatorLibrary translatorLibrary;
private DeviceInitializationPhaseHandler deviceInitPhaseHandler;
final HashedWheelTimer hashedWheelTimer,
final ConvertorExecutor convertorExecutor,
final boolean skipTableFeatures,
- final boolean useSingleLayerSerialization) {
+ final boolean useSingleLayerSerialization,
+ final DeviceInitializerProvider deviceInitializerProvider) {
this.dataBroker = dataBroker;
+ this.deviceInitializerProvider = deviceInitializerProvider;
/* merge empty nodes to oper DS to predict any problems with missing parent for Node */
final WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
connectionContext.setOutboundQueueHandleRegistration(outboundQueueHandlerRegistration);
final LifecycleService lifecycleService = new LifecycleServiceImpl();
-
final DeviceContext deviceContext = new DeviceContextImpl(
connectionContext,
dataBroker,
skipTableFeatures,
hashedWheelTimer,
this,
- useSingleLayerSerialization);
+ useSingleLayerSerialization,
+ deviceInitializerProvider);
deviceContext.setSalRoleService(new SalRoleServiceImpl(deviceContext, deviceContext));
deviceContexts.put(deviceInfo, deviceContext);
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.device.initialization;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.api.ConnectionException;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractDeviceInitializer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractDeviceInitializer.class);
+
+ /**
+ * Perform initial information gathering and store them to operational datastore
+ * @param deviceContext device context
+ * @param multipartWriterProvider multipart writer provider
+ */
+ public void initialize(@Nonnull final DeviceContext deviceContext,
+ final boolean switchFeaturesMandatory,
+ @Nullable final MultipartWriterProvider multipartWriterProvider,
+ @Nullable final ConvertorExecutor convertorExecutor) throws ExecutionException,InterruptedException {
+ Preconditions.checkNotNull(deviceContext);
+
+ // Write node to datastore
+ LOG.debug("Initializing node information for node {}", deviceContext.getDeviceInfo().getLOGValue());
+ try {
+ deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, deviceContext
+ .getDeviceInfo()
+ .getNodeInstanceIdentifier(),
+ new NodeBuilder()
+ .setId(deviceContext.getDeviceInfo().getNodeId())
+ .setNodeConnector(Collections.emptyList())
+ .build());
+ } catch (final Exception e) {
+ LOG.warn("Failed to write node {} to DS ", deviceContext.getDeviceInfo().getNodeId(), e);
+ throw new ExecutionException(new ConnectionException("Failed to write node " + deviceContext.getDeviceInfo().getNodeId() + " to DS ", e));
+ }
+
+ // Synchronously get information about device
+ initializeNodeInformation(deviceContext, switchFeaturesMandatory, multipartWriterProvider, convertorExecutor)
+ .get();
+ }
+
+ protected abstract Future<Void> initializeNodeInformation(@Nonnull final DeviceContext deviceContext,
+ final boolean switchFeaturesMandatory,
+ @Nullable final MultipartWriterProvider multipartWriterProvider,
+ @Nullable final ConvertorExecutor convertorExecutor);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.device.initialization;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class DeviceInitializerProvider {
+
+ private final Map<Short, AbstractDeviceInitializer> initializers = new HashMap<>();
+
+ /**
+ * Register device initializer.
+ *
+ * @param version the initializer version
+ * @param initializer the initializer instance
+ */
+ public void register(final Short version, final AbstractDeviceInitializer initializer) {
+ initializers.put(version, initializer);
+ }
+
+ /**
+ * Lookup device initializer.
+ *
+ * @param version the initializer version
+ * @return the initializer instance
+ */
+ public Optional<AbstractDeviceInitializer> lookup(final Short version) {
+ return Optional.ofNullable(initializers.get(version));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.device.initialization;
+
+import org.opendaylight.openflowplugin.api.OFConstants;
+
+/**
+ * Multipart writer provider factory
+ */
+public class DeviceInitializerProviderFactory {
+
+ /**
+ * Create default #{@link org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProvider}
+ * @return the device initialization provider
+ */
+ public static DeviceInitializerProvider createDefaultProvider() {
+ final DeviceInitializerProvider provider = new DeviceInitializerProvider();
+ provider.register(OFConstants.OFP_VERSION_1_0, new OF10DeviceInitializer());
+ provider.register(OFConstants.OFP_VERSION_1_3, new OF13DeviceInitializer());
+ return provider;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.device.initialization;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
+import java.util.concurrent.Future;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
+import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMultipartCollectorService;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerMultipartCollectorService;
+import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtil;
+import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OF10DeviceInitializer extends AbstractDeviceInitializer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OF10DeviceInitializer.class);
+
+ @Override
+ protected Future<Void> initializeNodeInformation(@Nonnull final DeviceContext deviceContext,
+ final boolean switchFeaturesMandatory,
+ @Nullable final MultipartWriterProvider multipartWriterProvider,
+ @Nullable final ConvertorExecutor convertorExecutor) {
+ final ConnectionContext connectionContext = Preconditions.checkNotNull(deviceContext.getPrimaryConnectionContext());
+ final DeviceState deviceState = Preconditions.checkNotNull(deviceContext.getDeviceState());
+ final DeviceInfo deviceInfo = Preconditions.checkNotNull(deviceContext.getDeviceInfo());
+ final CapabilitiesV10 capabilitiesV10 = connectionContext.getFeatures().getCapabilitiesV10();
+
+ // Set capabilities for this device based on capabilities of connection context
+ LOG.debug("Setting capabilities for device {}", deviceInfo.getLOGValue());
+ DeviceStateUtil.setDeviceStateBasedOnV10Capabilities(deviceState, capabilitiesV10);
+ final ListenableFuture<Boolean> future = requestMultipart(MultipartType.OFPMPDESC, deviceContext);
+
+ Futures.addCallback(future, new FutureCallback<Boolean>() {
+ @Override
+ public void onSuccess(@Nullable final Boolean result) {
+ if (Boolean.TRUE.equals(result)) {
+ LOG.debug("Creating empty flow capable node: {}", deviceInfo.getLOGValue());
+ makeEmptyFlowCapableNode(deviceContext, deviceInfo);
+
+ LOG.debug("Creating empty tables for {}", deviceInfo.getLOGValue());
+ DeviceInitializationUtil.makeEmptyTables(
+ deviceContext,
+ deviceInfo,
+ deviceContext.getPrimaryConnectionContext().getFeatures().getTables());
+ }
+ }
+
+ @Override
+ public void onFailure(@Nonnull final Throwable t) {
+ LOG.warn("Error occurred in preparation node {} for protocol 1.0", deviceInfo.getLOGValue());
+ LOG.trace("Error for node {} : ", deviceInfo.getLOGValue(), t);
+ }
+ });
+
+ return Futures.transform(future, new Function<Boolean, Void>() {
+ @Nullable
+ @Override
+ public Void apply(@Nullable final Boolean input) {
+ writePhyPortInformation(deviceContext);
+ return null;
+ }
+ });
+ }
+
+ private static void writePhyPortInformation(final DeviceContext deviceContext) {
+ final DeviceInfo deviceInfo = deviceContext.getDeviceInfo();
+ final ConnectionContext connectionContext = deviceContext.getPrimaryConnectionContext();
+ final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = deviceContext
+ .oook()
+ .lookupTranslator(new TranslatorKey(deviceInfo.getVersion(), PortGrouping.class.getName()));
+
+ connectionContext.getFeatures().getPhyPort().forEach(port -> {
+ final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
+ deviceInfo.getDatapathId(),
+ port.getPortNo(),
+ OpenflowVersion.get(deviceInfo.getVersion()));
+
+ try {
+ deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL,
+ deviceInfo
+ .getNodeInstanceIdentifier()
+ .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorId)),
+ new NodeConnectorBuilder()
+ .setId(nodeConnectorId)
+ .addAugmentation(
+ FlowCapableNodeConnector.class,
+ translator.translate(port, deviceInfo, null))
+ .addAugmentation(
+ FlowCapableNodeConnectorStatisticsData.class,
+ new FlowCapableNodeConnectorStatisticsDataBuilder().build())
+ .build());
+ } catch (final Exception e) {
+ LOG.debug("Failed to write node {} to DS ", deviceInfo.getLOGValue(), e);
+ }
+ });
+ }
+
+ private static void makeEmptyFlowCapableNode(final TxFacade txFacade, final DeviceInfo deviceInfo) {
+ try {
+ txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL,
+ deviceInfo
+ .getNodeInstanceIdentifier()
+ .augmentation(FlowCapableNode.class),
+ new FlowCapableNodeBuilder().build());
+ } catch (final Exception e) {
+ LOG.debug("Failed to write empty node {} to DS ", deviceInfo.getLOGValue(), e);
+ }
+ }
+
+ private static ListenableFuture<Boolean> requestMultipart(final MultipartType multipartType,
+ final DeviceContext deviceContext) {
+ if (deviceContext.canUseSingleLayerSerialization()) {
+ final SingleLayerMultipartCollectorService service =
+ new SingleLayerMultipartCollectorService(deviceContext, deviceContext);
+
+ return Futures.transform(service.handleServiceCall(multipartType), new Function<RpcResult<List<MultipartReply>>, Boolean>() {
+ @Nullable
+ @Override
+ public Boolean apply(final RpcResult<List<MultipartReply>> input) {
+ return input.isSuccessful();
+ }
+ });
+ }
+
+ final MultiLayerMultipartCollectorService service =
+ new MultiLayerMultipartCollectorService(deviceContext, deviceContext);
+
+ return Futures.transform(service.handleServiceCall(multipartType), new Function<RpcResult<List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply>>, Boolean>() {
+ @Nullable
+ @Override
+ public Boolean apply(final RpcResult<List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply>> input) {
+ return input.isSuccessful();
+ }
+ });
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.device.initialization;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
+import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMultipartCollectorService;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerMultipartCollectorService;
+import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtil;
+import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OF13DeviceInitializer extends AbstractDeviceInitializer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(OF13DeviceInitializer.class);
+
+ @Override
+ protected Future<Void> initializeNodeInformation(@Nonnull final DeviceContext deviceContext,
+ final boolean switchFeaturesMandatory,
+ @Nullable final MultipartWriterProvider multipartWriterProvider,
+ @Nullable final ConvertorExecutor convertorExecutor) {
+ final ConnectionContext connectionContext = Preconditions.checkNotNull(deviceContext.getPrimaryConnectionContext());
+ final DeviceState deviceState = Preconditions.checkNotNull(deviceContext.getDeviceState());
+ final DeviceInfo deviceInfo = Preconditions.checkNotNull(deviceContext.getDeviceInfo());
+ final Capabilities capabilities = connectionContext.getFeatures().getCapabilities();
+ LOG.debug("Setting capabilities for device {}", deviceInfo.getLOGValue());
+ DeviceStateUtil.setDeviceStateBasedOnV13Capabilities(deviceState, capabilities);
+
+ // First process description reply, write data to DS and write consequent data if successful
+ return Futures.transform(
+ requestMultipart(MultipartType.OFPMPDESC, deviceContext),
+ (AsyncFunction<RpcResult<List<OfHeader>>, Void>) input -> {
+ translateAndWriteResult(
+ MultipartType.OFPMPDESC,
+ input.getResult(),
+ deviceContext,
+ multipartWriterProvider,
+ convertorExecutor);
+
+ final List<ListenableFuture<RpcResult<List<OfHeader>>>> futures = new ArrayList<>();
+ futures.add(requestAndProcessMultipart(MultipartType.OFPMPMETERFEATURES, deviceContext, multipartWriterProvider, convertorExecutor));
+ futures.add(requestAndProcessMultipart(MultipartType.OFPMPGROUPFEATURES, deviceContext, multipartWriterProvider, convertorExecutor));
+ futures.add(requestAndProcessMultipart(MultipartType.OFPMPTABLEFEATURES, deviceContext, multipartWriterProvider, convertorExecutor));
+ futures.add(requestAndProcessMultipart(MultipartType.OFPMPPORTDESC, deviceContext, multipartWriterProvider, convertorExecutor));
+
+ return Futures.transform(
+ (switchFeaturesMandatory ? Futures.allAsList(futures) : Futures.successfulAsList(futures)),
+ new Function<List<RpcResult<List<OfHeader>>>, Void>() {
+ @Nullable
+ @Override
+ public Void apply(@Nullable final List<RpcResult<List<OfHeader>>> input) {
+ LOG.info("Static node {} successfully finished collecting", deviceContext.getDeviceInfo().getLOGValue());
+ return null;
+ }
+ });
+ });
+
+ }
+
+ /**
+ * Request multipart of specified type and then run some processing on it
+ * @param type multipart type
+ * @param deviceContext device context
+ * @param multipartWriterProvider multipart writer provider
+ * @param convertorExecutor convertor executor
+ * @return list of multipart messages unified to parent interface
+ */
+ private static ListenableFuture<RpcResult<List<OfHeader>>> requestAndProcessMultipart(final MultipartType type,
+ final DeviceContext deviceContext,
+ final MultipartWriterProvider multipartWriterProvider,
+ @Nullable final ConvertorExecutor convertorExecutor) {
+ final ListenableFuture<RpcResult<List<OfHeader>>> rpcResultListenableFuture =
+ MultipartType.OFPMPTABLEFEATURES.equals(type) && deviceContext.isSkipTableFeatures()
+ ? RpcResultBuilder.<List<OfHeader>>success().buildFuture()
+ : requestMultipart(type, deviceContext);
+
+ createCallback(type, rpcResultListenableFuture, deviceContext, multipartWriterProvider, convertorExecutor);
+ return rpcResultListenableFuture;
+ }
+
+ /**
+ * Inject callback ti future for specified multipart type. This callback will translate and write
+ * result of multipart messages
+ * @param type multipart type
+ * @param future multipart collection future
+ * @param deviceContext device context
+ * @param multipartWriterProvider multipart writer provider
+ * @param convertorExecutor convertor executor
+ */
+ private static void createCallback(final MultipartType type,
+ final ListenableFuture<RpcResult<List<OfHeader>>> future,
+ final DeviceContext deviceContext,
+ @Nullable final MultipartWriterProvider multipartWriterProvider,
+ @Nullable final ConvertorExecutor convertorExecutor) {
+ Futures.addCallback(future, new FutureCallback<RpcResult<List<OfHeader>>>() {
+ @Override
+ public void onSuccess(final RpcResult<List<OfHeader>> result) {
+ if (Objects.nonNull(result.getResult())) {
+ LOG.info("Static node {} info: {} collected", deviceContext.getDeviceInfo().getLOGValue(), type);
+ translateAndWriteResult(
+ type,
+ result.getResult(),
+ deviceContext,
+ multipartWriterProvider,
+ convertorExecutor);
+ } else {
+ result.getErrors().forEach(rpcError -> {
+ LOG.warn("Failed to retrieve static node {} info: {}", type, rpcError.getMessage());
+
+ if (LOG.isTraceEnabled() && Objects.nonNull(rpcError.getCause())) {
+ LOG.trace("Detailed error:", rpcError.getCause());
+ }
+ });
+
+ // If table features are disabled or returned nothing, at least make empty tables
+ if (MultipartType.OFPMPTABLEFEATURES.equals(type)) {
+ DeviceInitializationUtil.makeEmptyTables(
+ deviceContext,
+ deviceContext.getDeviceInfo(),
+ deviceContext.getPrimaryConnectionContext().getFeatures().getTables());
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(@Nonnull final Throwable t) {
+ LOG.warn("Request of type {} for static info of node {} failed.", type, deviceContext.getDeviceInfo().getLOGValue());
+ }
+ });
+ }
+
+ /**
+ * Translate and write multipart messages from OpenflowJava
+ * @param type multipart type
+ * @param result multipart messages
+ * @param deviceContext device context
+ * @param multipartWriterProvider multipart writer provider
+ * @param convertorExecutor convertor executor
+ */
+ private static void translateAndWriteResult(final MultipartType type,
+ final List<OfHeader> result,
+ final DeviceContext deviceContext,
+ @Nullable final MultipartWriterProvider multipartWriterProvider,
+ @Nullable final ConvertorExecutor convertorExecutor) {
+ if (Objects.nonNull(result)) {
+ try {
+ result.forEach(reply -> {
+ // First, translate collected data to proper openflowplugin representation
+ MultipartReplyTranslatorUtil
+ .translate(
+ reply,
+ deviceContext.getDeviceInfo(),
+ convertorExecutor,
+ deviceContext.oook())
+ .ifPresent(translatedReply -> {
+ // If we collected meter features, check if we have support for meters
+ // and pass this information to device context
+ if (MultipartType.OFPMPMETERFEATURES.equals(type) &&
+ translatedReply instanceof MeterFeatures) {
+ final MeterFeatures meterFeatures = (MeterFeatures) translatedReply;
+
+ if (meterFeatures.getMaxMeter().getValue() > 0) {
+ deviceContext.getDeviceState().setMeterAvailable(true);
+ }
+ }
+
+ // Now. try to write translated collected features
+ Optional.ofNullable(multipartWriterProvider)
+ .flatMap(provider -> provider.lookup(type))
+ .ifPresent(writer -> writer.write(translatedReply, false));
+ });
+ });
+ } catch (final Exception e) {
+ LOG.warn("Failed to write node {} to DS ", deviceContext.getDeviceInfo().getLOGValue(), e);
+ }
+ } else {
+ LOG.warn("Failed to write node {} to DS because we failed to gather device info.",
+ deviceContext.getDeviceInfo().getLOGValue());
+ }
+ }
+
+ /**
+ * Send request to device and unify different possible reply types from OpenflowJava to common parent interface
+ * @param multipartType multipart type
+ * @param deviceContext device context
+ * @return unified replies
+ */
+ private static ListenableFuture<RpcResult<List<OfHeader>>> requestMultipart(final MultipartType multipartType,
+ final DeviceContext deviceContext) {
+ if (deviceContext.canUseSingleLayerSerialization()) {
+ final SingleLayerMultipartCollectorService service =
+ new SingleLayerMultipartCollectorService(deviceContext, deviceContext);
+
+ return Futures.transform(service.handleServiceCall(multipartType), new Function<RpcResult<List<MultipartReply>>, RpcResult<List<OfHeader>>>() {
+ @Nullable
+ @Override
+ public RpcResult<List<OfHeader>> apply(final RpcResult<List<MultipartReply>> input) {
+ if (Objects.isNull(input.getResult()) && input.isSuccessful()) {
+ final List<OfHeader> temp = null;
+ return RpcResultBuilder.success(temp).build();
+ }
+
+ return input.isSuccessful()
+ ? RpcResultBuilder.success(input
+ .getResult()
+ .stream()
+ .map(reply -> (OfHeader) reply)
+ .collect(Collectors.toList()))
+ .build()
+ : RpcResultBuilder.<List<OfHeader>>failed()
+ .withRpcErrors(input.getErrors())
+ .build();
+ }
+ });
+ }
+
+ final MultiLayerMultipartCollectorService service =
+ new MultiLayerMultipartCollectorService(deviceContext, deviceContext);
+
+ return Futures.transform(service.handleServiceCall(multipartType), new Function<RpcResult<List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply>>, RpcResult<List<OfHeader>>>() {
+ @Nullable
+ @Override
+ public RpcResult<List<OfHeader>> apply(final RpcResult<List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply>> input) {
+ if (Objects.isNull(input.getResult()) && input.isSuccessful()) {
+ final List<OfHeader> temp = null;
+ return RpcResultBuilder.success(temp).build();
+ }
+
+ return input.isSuccessful()
+ ? RpcResultBuilder.success(input
+ .getResult()
+ .stream()
+ .map(reply -> (OfHeader) reply)
+ .collect(Collectors.toList()))
+ .build()
+ : RpcResultBuilder.<List<OfHeader>>failed()
+ .withRpcErrors(input.getErrors())
+ .build();
+ }
+ });
+ }
+
+}
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceReplyProcessor;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
* </p>
* Created: Mar 23, 2015
*/
-public class MultiMsgCollectorImpl implements MultiMsgCollector {
-
+public class MultiMsgCollectorImpl<T extends OfHeader> implements MultiMsgCollector<T> {
private static final Logger LOG = LoggerFactory.getLogger(MultiMsgCollectorImpl.class);
-
- private final List<MultipartReply> replyCollection = new ArrayList<>();
- private final RequestContext<List<MultipartReply>> requestContext;
+ private final List<T> replyCollection = new ArrayList<>();
+ private final RequestContext<List<T>> requestContext;
private final DeviceReplyProcessor deviceReplyProcessor;
- private MultipartType msgType;
- public MultiMsgCollectorImpl(final DeviceReplyProcessor deviceReplyProcessor, final RequestContext<List<MultipartReply>> requestContext) {
+ public MultiMsgCollectorImpl(final DeviceReplyProcessor deviceReplyProcessor, final RequestContext<List<T>> requestContext) {
this.deviceReplyProcessor = Preconditions.checkNotNull(deviceReplyProcessor);
this.requestContext = Preconditions.checkNotNull(requestContext);
}
@Override
- public void addMultipartMsg(final MultipartReply reply) {
- addMultipartMsg(reply, null);
- }
-
- @Override
- public void addMultipartMsg(@Nonnull final MultipartReply reply, @Nonnull final EventIdentifier eventIdentifier) {
+ public void addMultipartMsg(@Nonnull final T reply, final boolean reqMore, @Nullable final EventIdentifier eventIdentifier) {
Preconditions.checkNotNull(reply);
+ Preconditions.checkNotNull(requestContext.getXid());
Preconditions.checkArgument(requestContext.getXid().getValue().equals(reply.getXid()));
LOG.trace("Try to add Multipart reply msg with XID {}", reply.getXid());
-
- if (msgType == null) {
- msgType = reply.getType();
- }
-
- if (!msgType.equals(reply.getType())) {
- LOG.warn("MultiMsgCollector get incorrect multipart msg with type {} but expected type is {}", reply.getType(), msgType);
- }
-
replyCollection.add(reply);
- if (!reply.getFlags().isOFPMPFREQMORE()) {
+
+ if (!reqMore) {
endCollecting(eventIdentifier);
}
}
- public void endCollecting() {
- endCollecting(null);
- }
+ @Override
+ public void endCollecting(@Nullable final EventIdentifier eventIdentifier) {
+ final RpcResult<List<T>> rpcResult = RpcResultBuilder.success(replyCollection).build();
- public void endCollecting(final EventIdentifier eventIdentifier) {
- final RpcResult<List<MultipartReply>> rpcResult = RpcResultBuilder.success(replyCollection).build();
- if (null != eventIdentifier) {
+ if (Objects.nonNull(eventIdentifier)) {
EventsTimeCounter.markEnd(eventIdentifier);
}
+
requestContext.setResult(rpcResult);
requestContext.close();
deviceReplyProcessor.processReply(requestContext.getXid(), replyCollection);
MatchDeserializerInjector.injectDeserializers(provider);
ActionDeserializerInjector.injectDeserializers(provider);
InstructionDeserializerInjector.injectDeserializers(provider);
- MessageDeserializerInjector.injectDeserializers(provider);
MultipartDeserializerInjector.injectDeserializers(provider);
+
+ // Message deserializers are not used, so disable them here
+ // Uncomment to enable
+ // MessageDeserializerInjector.injectDeserializers(provider);
}
}
message.skipBytes(PADDING_IN_GROUP_DESC_HEADER);
itemBuilder.setGroupId(new GroupId(message.readUnsignedInt()));
+ itemBuilder.setKey(new GroupDescStatsKey(itemBuilder.getGroupId()));
final List<Bucket> subItems = new ArrayList<>();
int actualLength = GROUP_DESC_HEADER_LENGTH;
.setWatchPort(message.readUnsignedInt())
.setWatchGroup(message.readUnsignedInt());
- bucketKey++;
-
message.skipBytes(PADDING_IN_BUCKETS_HEADER);
final List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list
.Action> actions = new ArrayList<>();
bucketBuilder.setAction(actions);
subItems.add(bucketBuilder.build());
+ bucketKey++;
actualLength += bucketsLength;
}
items.add(itemBuilder
- .setKey(new GroupDescStatsKey(itemBuilder.getGroupId()))
.setBuckets(new BucketsBuilder()
.setBucket(subItems)
.build())
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.statistics.services;
+package org.opendaylight.openflowplugin.impl.services;
import com.google.common.base.MoreObjects;
+import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
+import org.opendaylight.yangtools.yang.common.RpcResult;
-final class MatchingFlowsInTableService extends AbstractMultipartService<GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput> {
+public abstract class AbstractAggregateFlowMultipartService<T extends OfHeader>
+ extends AbstractMultipartService<GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput, T> {
private final ConvertorExecutor convertorExecutor;
- public MatchingFlowsInTableService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
+ public AbstractAggregateFlowMultipartService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
super(requestContextStack, deviceContext);
this.convertorExecutor = convertorExecutor;
}
protected OfHeader buildRequest(final Xid xid, final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) throws ServiceException {
final MultipartRequestAggregateCaseBuilder multipartRequestAggregateCaseBuilder = new MultipartRequestAggregateCaseBuilder();
final MultipartRequestAggregateBuilder mprAggregateRequestBuilder = new MultipartRequestAggregateBuilder();
- final short tableId = MoreObjects.firstNonNull(input.getTableId(), OFConstants.OFPTT_ALL).shortValue();
+ final short tableId = MoreObjects.firstNonNull(input.getTableId(), OFConstants.OFPTT_ALL);
mprAggregateRequestBuilder.setTableId(tableId);
long outputPortValue = MoreObjects.firstNonNull(input.getOutPort(), OFConstants.OFPP_ANY).longValue();
mprAggregateRequestBuilder.setOutPort(outputPortValue);
} else {
mprAggregateRequestBuilder.setCookieMask(MoreObjects.firstNonNull(input.getCookieMask().getValue(), OFConstants.DEFAULT_COOKIE_MASK));
}
- long outGroup = MoreObjects.firstNonNull(input.getOutGroup(), OFConstants.OFPG_ANY).longValue();
+ long outGroup = MoreObjects.firstNonNull(input.getOutGroup(), OFConstants.OFPG_ANY);
mprAggregateRequestBuilder.setOutGroup(outGroup);
} else {
mprAggregateRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
return mprInput.build();
}
+
+ /**
+ * Process input and return reply
+ * @param input input
+ * @return reply
+ */
+ public abstract Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> handleAndReply(
+ final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input);
+
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services;
+
+import java.util.Objects;
+import java.util.concurrent.Future;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava;
+import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
+import org.opendaylight.openflowplugin.extension.api.exception.ConverterNotFoundException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public abstract class AbstractExperimenterMultipartService<T extends OfHeader> extends AbstractMultipartService<SendExperimenterMpRequestInput, T> {
+
+ private final ExtensionConverterProvider extensionConverterProvider;
+
+ protected AbstractExperimenterMultipartService(RequestContextStack requestContextStack, DeviceContext deviceContext,
+ ExtensionConverterProvider extensionConverterProvider) {
+ super(requestContextStack, deviceContext);
+ this.extensionConverterProvider = extensionConverterProvider;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected OfHeader buildRequest(Xid xid, SendExperimenterMpRequestInput input) throws ServiceException {
+ final TypeVersionKey key = new TypeVersionKey<>(
+ input.getExperimenterMessageOfChoice().getImplementedInterface(),
+ getVersion());
+
+ final ConvertorMessageToOFJava<ExperimenterMessageOfChoice, ExperimenterDataOfChoice> messageConverter =
+ getExtensionConverterProvider().getMessageConverter(key);
+
+ if (Objects.isNull(messageConverter)) {
+ throw new ServiceException(new ConverterNotFoundException(key.toString()));
+ }
+
+ try {
+ return RequestInputUtils
+ .createMultipartHeader(MultipartType.OFPMPEXPERIMENTER, xid.getValue(), getVersion())
+ .setMultipartRequestBody(new MultipartRequestExperimenterCaseBuilder()
+ .setMultipartRequestExperimenter(new MultipartRequestExperimenterBuilder()
+ .setExperimenter(messageConverter.getExperimenterId())
+ .setExpType(messageConverter.getType())
+ .setExperimenterDataOfChoice(messageConverter
+ .convert(input.getExperimenterMessageOfChoice()))
+ .build())
+ .build())
+ .build();
+ } catch (final ConversionException e) {
+ throw new ServiceException(e);
+ }
+ }
+
+ /**
+ * Get extension converter provider
+ * @return extension converter provider
+ */
+ protected ExtensionConverterProvider getExtensionConverterProvider() {
+ return extensionConverterProvider;
+ }
+
+ /**
+ * Process experimenter input and result experimenter output
+ * @param input experimenter input
+ * @return experimenter output
+ */
+ public abstract Future<RpcResult<SendExperimenterMpRequestOutput>> handleAndReply(SendExperimenterMpRequestInput input);
+
+}
+++ /dev/null
-/**
- * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.services;
-
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.yangtools.concepts.Builder;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-
-abstract class AbstractMessageService<R extends DataObject, I extends Builder<? extends R>, O extends DataObject>
- extends AbstractSimpleService<R, O> {
- private final boolean useSingleLayerSerialization;
-
- protected AbstractMessageService(RequestContextStack requestContextStack, DeviceContext deviceContext, Class<O> clazz) {
- super(requestContextStack, deviceContext, clazz);
- useSingleLayerSerialization = deviceContext.isUseSingleLayerSerialization();
- }
-
- @Override
- public ListenableFuture<RpcResult<O>> handleServiceCall(R input) {
- return Futures.withFallback(super.handleServiceCall(input), t -> RpcResultBuilder.<O>failed().buildFuture());
- }
-
- /**
- * Check if this service is supported in current OpenFlowPlugin configuration
- * @return true if supported and single layer serialization is turned on
- */
- public boolean isSupported() {
- return useSingleLayerSerialization;
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.openflowplugin.impl.services;
+
+import com.google.common.util.concurrent.FutureCallback;
+import java.util.List;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory;
+import org.opendaylight.openflowplugin.impl.util.DeviceInitializationUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+
+public abstract class AbstractMultipartCollectorService<T extends OfHeader> extends AbstractMultipartService<MultipartType, T> {
+
+ protected AbstractMultipartCollectorService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
+ super(requestContextStack, deviceContext);
+ }
+
+ @Override
+ protected FutureCallback<OfHeader> createCallback(RequestContext<List<T>> context, Class<?> requestType) {
+ final FutureCallback<OfHeader> callback = super.createCallback(context, requestType);
+
+ return new FutureCallback<OfHeader>() {
+ @Override
+ public void onSuccess(@Nullable final OfHeader result) {
+ callback.onSuccess(result);
+ }
+
+ @Override
+ public void onFailure(@Nonnull final Throwable t) {
+ // If we failed getting table features, at least create empty tables
+ if (MultipartType.OFPMPTABLEFEATURES.getClass().equals(requestType)) {
+ DeviceInitializationUtil.makeEmptyTables(
+ getTxFacade(),
+ getDeviceInfo(),
+ getDeviceContext().getPrimaryConnectionContext().getFeatures().getTables());
+ }
+
+ callback.onFailure(t);
+ }
+ };
+ }
+
+ @Override
+ protected OfHeader buildRequest(final Xid xid, final MultipartType input) {
+ return MultipartRequestInputFactory.makeMultipartRequestInput(xid.getValue(), getVersion(), input);
+ }
+}
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerFlowMultipartRequestOnTheFlyCallback;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerFlowMultipartRequestOnTheFlyCallback;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
-public abstract class AbstractMultipartOnTheFlyService<I> extends AbstractService<I, List<MultipartReply>> {
+public abstract class AbstractMultipartOnTheFlyService<I, T extends OfHeader> extends AbstractMultipartService<I, T> {
+
private final ConvertorExecutor convertorExecutor;
+ private final MultipartWriterProvider statisticsWriterProvider;
- protected AbstractMultipartOnTheFlyService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
+ protected AbstractMultipartOnTheFlyService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
super(requestContextStack, deviceContext);
this.convertorExecutor = convertorExecutor;
+ this.statisticsWriterProvider = statisticsWriterProvider;
}
@Override
- protected final FutureCallback<OfHeader> createCallback(final RequestContext<List<MultipartReply>> context, final Class<?> requestType) {
- return new MultipartRequestOnTheFlyCallback(context, requestType,
- getMessageSpy(), getEventIdentifier(), getDeviceInfo(),
- getDeviceContext().getDeviceFlowRegistry(), getTxFacade(),
- convertorExecutor);
+ protected final FutureCallback<OfHeader> createCallback(final RequestContext<List<T>> context, final Class<?> requestType) {
+ return canUseSingleLayerSerialization()
+ ? new SingleLayerFlowMultipartRequestOnTheFlyCallback<>(context, requestType, getDeviceContext(), getEventIdentifier(), statisticsWriterProvider)
+ : new MultiLayerFlowMultipartRequestOnTheFlyCallback<>(context, requestType, getDeviceContext(), getEventIdentifier(), statisticsWriterProvider, convertorExecutor);
}
-
}
package org.opendaylight.openflowplugin.impl.services;
import java.util.List;
+import java.util.Objects;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-final class MultipartRequestCallback extends AbstractRequestCallback<List<MultipartReply>> {
- private static final Logger LOG = LoggerFactory.getLogger(MultipartRequestCallback.class);
- private final MultiMsgCollector collector;
+public abstract class AbstractMultipartRequestCallback<T extends OfHeader> extends AbstractRequestCallback<List<T>> {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipartRequestCallback.class);
+ private final MultiMsgCollector<T> collector;
- public MultipartRequestCallback(final RequestContext<List<MultipartReply>> context, final Class<?> requestType, final DeviceContext deviceContext) {
- super(context, requestType, deviceContext.getMessageSpy());
- collector = deviceContext.getMultiMsgCollector(context);
- }
-
- public MultipartRequestCallback(final RequestContext<List<MultipartReply>> context,
- final Class<?> requestType,
- final DeviceContext deviceContext,
- final EventIdentifier eventIdentifier) {
+ public AbstractMultipartRequestCallback(
+ final RequestContext<List<T>> context,
+ final Class<?> requestType,
+ final DeviceContext deviceContext,
+ final EventIdentifier eventIdentifier) {
super(context, requestType, deviceContext.getMessageSpy(), eventIdentifier);
collector = deviceContext.getMultiMsgCollector(context);
}
@Override
+ @SuppressWarnings("unchecked")
public void onSuccess(final OfHeader result) {
- if (result == null) {
- LOG.info("Ofheader was null.");
+ if (Objects.isNull(result)) {
+ LOG.info("Response received was null.");
collector.endCollecting(getEventIdentifier());
return;
}
- if (!(result instanceof MultipartReply)) {
+ if (!isMultipart(result)) {
LOG.info("Unexpected response type received {}.", result.getClass());
- final RpcResultBuilder<List<MultipartReply>> rpcResultBuilder =
- RpcResultBuilder.<List<MultipartReply>>failed().withError(RpcError.ErrorType.APPLICATION,
- String.format("Unexpected response type received %s.", result.getClass()));
- setResult(rpcResultBuilder.build());
+
+ setResult(RpcResultBuilder
+ .<List<T>>failed()
+ .withError(RpcError.ErrorType.APPLICATION,
+ String.format("Unexpected response type received %s.", result.getClass()))
+ .build());
} else {
- collector.addMultipartMsg((MultipartReply) result, getEventIdentifier());
+ final T resultCast = (T) result;
+ collector.addMultipartMsg(resultCast, isReqMore(resultCast), getEventIdentifier());
}
}
+ /**
+ * Check if result is multipart
+ * @param result result
+ * @return true if result is multipart
+ */
+ protected abstract boolean isMultipart(final OfHeader result);
+
+ /**
+ * Check if result requests more multiparts
+ * @param result result
+ * @return true if result requests more multiparts
+ */
+ protected abstract boolean isReqMore(final T result);
+
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.openflowplugin.impl.services;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class AbstractMultipartRequestOnTheFlyCallback<T extends OfHeader> extends AbstractMultipartRequestCallback<T> {
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipartRequestOnTheFlyCallback.class);
+ private final DeviceInfo deviceInfo;
+ private boolean finished = false;
+ private final EventIdentifier doneEventIdentifier;
+ private final TxFacade txFacade;
+ private final MultipartWriterProvider statisticsWriterProvider;
+
+ public AbstractMultipartRequestOnTheFlyCallback(final RequestContext<List<T>> context, Class<?> requestType,
+ final DeviceContext deviceContext,
+ final EventIdentifier eventIdentifier,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(context, requestType, deviceContext, eventIdentifier);
+ deviceInfo = deviceContext.getDeviceInfo();
+ doneEventIdentifier = new EventIdentifier(getMultipartType().name(), deviceContext.getDeviceInfo().getNodeId().toString());
+ txFacade = deviceContext;
+ this.statisticsWriterProvider = statisticsWriterProvider;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void onSuccess(final OfHeader result) {
+ if (Objects.isNull(result)) {
+ LOG.info("OfHeader was null.");
+ if (!finished) {
+ endCollecting();
+ return;
+ }
+ } else if (finished) {
+ LOG.debug("Unexpected multipart response received: xid={}, {}", result.getXid(), result.getImplementedInterface());
+ return;
+ }
+
+ if (!isMultipart(result)) {
+ LOG.info("Unexpected response type received {}.", result.getClass());
+ setResult(RpcResultBuilder.<List<T>>failed().withError(RpcError.ErrorType.APPLICATION,
+ String.format("Unexpected response type received %s.", result.getClass())).build());
+ endCollecting();
+ } else {
+ final T resultCast = (T) result;
+
+ Futures.transform(processStatistics(resultCast), (Function<Optional<? extends MultipartReplyBody>, Void>) input -> {
+ input.ifPresent(reply -> {
+ try {
+ statisticsWriterProvider
+ .lookup(getMultipartType())
+ .ifPresent(writer -> writer.write(reply, false));
+ } catch (final Exception ex) {
+ LOG.warn("Stats processing of type {} for node {} failed during write-to-tx step",
+ getMultipartType(), deviceInfo.getLOGValue(), ex);
+ }
+ });
+
+ if (!isReqMore(resultCast)) {
+ endCollecting();
+ }
+
+ return null;
+ });
+ }
+ }
+
+ /**
+ * Get tx facade
+ * @return tx facade
+ */
+ protected TxFacade getTxFacade() {
+ return txFacade;
+ }
+
+ /**
+ * Ends collecting of multipart data
+ */
+ private void endCollecting() {
+ EventsTimeCounter.markEnd(doneEventIdentifier);
+ EventsTimeCounter.markEnd(getEventIdentifier());
+ spyMessage(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS);
+ txFacade.submitTransaction();
+ setResult(RpcResultBuilder.success(Collections.<T>emptyList()).build());
+ finished = true;
+ }
+
+ /**
+ * Process statistics.
+ *
+ * @param result result
+ */
+ protected abstract ListenableFuture<Optional<? extends MultipartReplyBody>> processStatistics(final T result);
+
+ /**
+ * Get multipart type
+ * @return multipart type
+ */
+ protected abstract MultipartType getMultipartType();
+
+
+}
package org.opendaylight.openflowplugin.impl.services;
import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
+import java.util.function.Function;
+import javax.annotation.Nonnull;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMultipartRequestCallback;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerMultipartRequestCallback;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public abstract class AbstractMultipartService<I, T extends OfHeader> extends AbstractService<I, List<T>> {
+
+ private static final Function<OfHeader, Boolean> ALTERNATE_IS_COMPLETE = message ->
+ !(message instanceof MultipartReply) || !((MultipartReply) message).isRequestMore();
-public abstract class AbstractMultipartService<I> extends AbstractService<I, List<MultipartReply>> {
protected AbstractMultipartService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
super(requestContextStack, deviceContext);
}
@Override
- protected final FutureCallback<OfHeader> createCallback(final RequestContext<List<MultipartReply>> context, final Class<?> requestType) {
- return new MultipartRequestCallback(context, requestType, getDeviceContext(), getEventIdentifier());
+ protected FutureCallback<OfHeader> createCallback(RequestContext<List<T>> context, Class<?> requestType) {
+ return canUseSingleLayerSerialization()
+ ? new SingleLayerMultipartRequestCallback<>(context, requestType, getDeviceContext(), getEventIdentifier())
+ : new MultiLayerMultipartRequestCallback<>(context, requestType, getDeviceContext(), getEventIdentifier());
}
+ @Override
+ public final ListenableFuture<RpcResult<List<T>>> handleServiceCall(@Nonnull final I input) {
+ return canUseSingleLayerSerialization()
+ ? super.handleServiceCall(input, ALTERNATE_IS_COMPLETE)
+ : super.handleServiceCall(input);
+ }
}
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy.STATISTIC_GROUP;
+import org.opendaylight.openflowplugin.impl.services.util.RequestContextUtil;
import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-abstract class AbstractRequestCallback<T> implements FutureCallback<OfHeader> {
+public abstract class AbstractRequestCallback<T> implements FutureCallback<OfHeader> {
private final RequestContext<T> context;
private final Class<?> requestType;
private final MessageSpy spy;
private EventIdentifier eventIdentifier;
-
- protected AbstractRequestCallback(final RequestContext<T> context, final Class<?> requestType, final MessageSpy spy) {
- this.context = Preconditions.checkNotNull(context);
- this.requestType = Preconditions.checkNotNull(requestType);
- this.spy = Preconditions.checkNotNull(spy);
- }
-
protected AbstractRequestCallback(final RequestContext<T> context,
final Class<?> requestType,
final MessageSpy spy,
}
@Override
- public final void onFailure(final Throwable t) {
+ public final void onFailure(@Nonnull final Throwable t) {
final RpcResultBuilder<T> builder;
if (null != eventIdentifier) {
EventsTimeCounter.markEnd(eventIdentifier);
import java.util.Objects;
import java.util.function.Function;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.impl.services.util.RequestContextUtil;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-abstract class AbstractService<I, O> {
+public abstract class AbstractService<I, O> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractService.class);
private final short version;
this.messageSpy = deviceContext.getMessageSpy();
}
+ public boolean canUseSingleLayerSerialization() {
+ return deviceContext.canUseSingleLayerSerialization();
+ }
+
public EventIdentifier getEventIdentifier() {
return eventIdentifier;
}
return deviceContext;
}
- protected DeviceRegistry getDeviceRegistry() {
+ public DeviceRegistry getDeviceRegistry() {
return deviceContext;
}
}
public ListenableFuture<RpcResult<O>> handleServiceCall(@Nonnull final I input,
- @Nonnull final Function<OfHeader, Boolean> isComplete) {
+ @Nullable final Function<OfHeader, Boolean> isComplete) {
Preconditions.checkNotNull(input);
- final Class<?> requestType;
- if (input instanceof DataContainer) {
- requestType = ((DataContainer) input).getImplementedInterface();
- } else {
- requestType = input.getClass();
- }
+ final Class<?> requestType = input instanceof DataContainer
+ ? DataContainer.class.cast(input).getImplementedInterface()
+ : input.getClass();
+
getMessageSpy().spyMessage(requestType, MessageSpy.STATISTIC_GROUP.TO_SWITCH_ENTERED);
LOG.trace("Handling general service call");
final RequestContext<O> requestContext = requestContextStack.createRequestContext();
- if (requestContext == null) {
+
+ if (Objects.isNull(requestContext)) {
LOG.trace("Request context refused.");
getMessageSpy().spyMessage(AbstractService.class, MessageSpy.STATISTIC_GROUP.TO_SWITCH_DISREGARDED);
- return failedFuture();
+ return Futures.immediateFuture(RpcResultBuilder
+ .<O>failed()
+ .withError(RpcError.ErrorType.APPLICATION, "", "Request quota exceeded")
+ .build());
}
- if (requestContext.getXid() == null) {
+ if (Objects.isNull(requestContext.getXid())) {
getMessageSpy().spyMessage(requestContext.getClass(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_RESERVATION_REJECTED);
return RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID.");
}
return requestContext.getFuture();
}
-
- protected static <T> ListenableFuture<RpcResult<T>> failedFuture() {
- final RpcResult<T> rpcResult = RpcResultBuilder.<T>failed()
- .withError(RpcError.ErrorType.APPLICATION, "", "Request quota exceeded").build();
- return Futures.immediateFuture(rpcResult);
- }
}
--- /dev/null
+/**
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services;
+
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.function.Function;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+public abstract class AbstractSilentErrorService<I, O extends DataObject>
+ extends AbstractSimpleService<I, O> {
+
+ protected AbstractSilentErrorService(RequestContextStack requestContextStack, DeviceContext deviceContext, Class<O> clazz) {
+ super(requestContextStack, deviceContext, clazz);
+ }
+
+ @Override
+ public ListenableFuture<RpcResult<O>> handleServiceCall(@Nonnull I input,
+ @Nullable final Function<OfHeader, Boolean> isComplete) {
+ return Futures.withFallback(
+ super.handleServiceCall(input, isComplete),
+ t -> RpcResultBuilder.<O>failed().buildFuture());
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.Future;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.TableUpdatedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public abstract class AbstractTableMultipartService<T extends OfHeader> extends AbstractMultipartService<UpdateTableInput, T> {
+
+ private final ConvertorExecutor convertorExecutor;
+ private final MultipartWriterProvider multipartWriterProvider;
+ private final VersionConvertorData data;
+
+ protected AbstractTableMultipartService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider multipartWriterProvider) {
+ super(requestContextStack, deviceContext);
+ this.convertorExecutor = convertorExecutor;
+ this.multipartWriterProvider = multipartWriterProvider;
+ data = new VersionConvertorData(getVersion());
+ }
+
+ @Override
+ protected OfHeader buildRequest(final Xid xid, final UpdateTableInput input) throws ServiceException {
+ final Optional<List<TableFeatures>> tableFeatures = getConvertorExecutor().convert(input.getUpdatedTable(), data);
+
+ return RequestInputUtils.createMultipartHeader(MultipartType.OFPMPTABLEFEATURES, xid.getValue(), getVersion())
+ .setMultipartRequestBody(new MultipartRequestTableFeaturesCaseBuilder()
+ .setMultipartRequestTableFeatures(new MultipartRequestTableFeaturesBuilder()
+ .setTableFeatures(tableFeatures
+ .orElseGet(Collections::emptyList))
+ .build())
+ .build())
+ .build();
+ }
+
+ /**
+ * Get convertor executor
+ * @return convertor executor
+ */
+ protected ConvertorExecutor getConvertorExecutor() {
+ return convertorExecutor;
+ }
+
+ /**
+ * Get data
+ * @return data
+ */
+ protected VersionConvertorData getData() {
+ return data;
+ }
+
+ /**
+ * Stores table features to operational datastore
+ */
+ protected void storeStatistics(List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures> result) {
+ multipartWriterProvider
+ .lookup(MultipartType.OFPMPTABLEFEATURES)
+ .ifPresent(writer -> {
+ writer.write(
+ new TableUpdatedBuilder()
+ .setTableFeatures(result)
+ .build(),
+ false);
+
+ getTxFacade().submitTransaction();
+ });
+ }
+
+ /**
+ * Process experimenter input and result experimenter output
+ * @param input experimenter input
+ * @return experimenter output
+ */
+ public abstract Future<RpcResult<UpdateTableOutput>> handleAndReply(UpdateTableInput input);
+
+}
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-public abstract class AbstractVoidService<T extends DataObject> extends AbstractService<T, Void> {
+public abstract class AbstractVoidService<T> extends AbstractService<T, Void> {
protected AbstractVoidService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
super(requestContextStack, deviceContext);
}
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
.setVersion(getVersion())
.build();
}
-}
\ No newline at end of file
+}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.openflowplugin.impl.services;
-
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.Collections;
-import java.util.List;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
-import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
-import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
-import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
-import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
-import org.opendaylight.openflowplugin.impl.statistics.SinglePurposeMultipartReplyTranslator;
-import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils;
-import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class MultipartRequestOnTheFlyCallback extends AbstractRequestCallback<List<MultipartReply>> {
- private static final Logger LOG = LoggerFactory.getLogger(MultipartRequestOnTheFlyCallback.class);
- private final SinglePurposeMultipartReplyTranslator multipartReplyTranslator;
- private final DeviceInfo deviceInfo;
- private final DeviceFlowRegistry registry;
- private boolean virgin = true;
- private boolean finished = false;
- private final EventIdentifier doneEventIdentifier;
- private final TxFacade txFacade;
-
-
- public MultipartRequestOnTheFlyCallback(final RequestContext<List<MultipartReply>> context,
- final Class<?> requestType,
- final MessageSpy messageSpy,
- final EventIdentifier eventIdentifier,
- final DeviceInfo deviceInfo,
- final DeviceFlowRegistry registry,
- final TxFacade txFacade,
- final ConvertorExecutor convertorExecutor) {
- super(context, requestType, messageSpy, eventIdentifier);
-
- this.deviceInfo = deviceInfo;
- this.registry = registry;
- this.txFacade = txFacade;
-
- multipartReplyTranslator = new SinglePurposeMultipartReplyTranslator(convertorExecutor);
-
- //TODO: this is focused on flow stats only - need more general approach if used for more than flow stats
- doneEventIdentifier = new EventIdentifier(MultipartType.OFPMPFLOW.name(), deviceInfo.getNodeId().toString());
- }
-
- public EventIdentifier getDoneEventIdentifier() {
- return doneEventIdentifier;
- }
-
- @Override
- public void onSuccess(final OfHeader result) {
- if (result == null) {
- LOG.info("Ofheader was null.");
- if (!finished) {
- endCollecting();
- return;
- }
- } else if (finished) {
- LOG.debug("Unexpected multipart response received: xid={}, {}", result.getXid(), result.getImplementedInterface());
- return;
- }
-
- if (!(result instanceof MultipartReply)) {
- LOG.info("Unexpected response type received {}.", result.getClass());
- final RpcResultBuilder<List<MultipartReply>> rpcResultBuilder =
- RpcResultBuilder.<List<MultipartReply>>failed().withError(RpcError.ErrorType.APPLICATION,
- String.format("Unexpected response type received %s.", result.getClass()));
- setResult(rpcResultBuilder.build());
- endCollecting();
- } else {
- final MultipartReply multipartReply = (MultipartReply) result;
-
- final MultipartReply singleReply = multipartReply;
- final List<? extends DataObject> multipartDataList = multipartReplyTranslator.translate(
- deviceInfo.getDatapathId(), deviceInfo.getVersion(), singleReply);
- final Iterable<? extends DataObject> allMultipartData = multipartDataList;
-
- //TODO: following part is focused on flow stats only - need more general approach if used for more than flow stats
- ListenableFuture<Void> future;
- if (virgin) {
- future = StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo, registry, txFacade);
- virgin = false;
- } else {
- future = Futures.immediateFuture(null);
- }
-
- Futures.transform(future, new Function<Void, Void>() {
-
- @Override
- public Void apply(final Void input) {
- StatisticsGatheringUtils.writeFlowStatistics((Iterable<FlowsStatisticsUpdate>) allMultipartData,
- deviceInfo, registry, txFacade);
-
- if (!multipartReply.getFlags().isOFPMPFREQMORE()) {
- endCollecting();
- }
- return input;
- }
- });
- }
- }
-
- private void endCollecting() {
- EventsTimeCounter.markEnd(getDoneEventIdentifier());
- EventsTimeCounter.markEnd(getEventIdentifier());
- final RpcResult<List<MultipartReply>> rpcResult = RpcResultBuilder.success(Collections.<MultipartReply>emptyList()).build();
- spyMessage(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_TRANSLATE_OUT_SUCCESS);
- txFacade.submitTransaction();
- setResult(rpcResult);
- finished = true;
- }
-}
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.impl.role.RoleChangeException;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ControllerRole;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
private final DeviceContext deviceContext;
- protected RoleService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<RoleRequestOutput> clazz) {
+ public RoleService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<RoleRequestOutput> clazz) {
super(requestContextStack, deviceContext, clazz);
this.deviceContext = deviceContext;
}
+++ /dev/null
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.openflowplugin.impl.services;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.Future;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
-import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.slf4j.Logger;
-
-public final class SalTableServiceImpl extends AbstractMultipartService<UpdateTableInput> implements SalTableService {
- private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(SalTableServiceImpl.class);
- private final TxFacade txFacade;
- private final ConvertorExecutor convertorExecutor;
- private final VersionConvertorData data;
-
- public SalTableServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
- super(requestContextStack, deviceContext);
- this.txFacade = deviceContext;
- this.convertorExecutor = convertorExecutor;
- data = new VersionConvertorData(getVersion());
- }
-
- @Override
- public Future<RpcResult<UpdateTableOutput>> updateTable(final UpdateTableInput input) {
- final ListenableFuture<RpcResult<List<MultipartReply>>> multipartFuture = handleServiceCall(input);
- final SettableFuture<RpcResult<UpdateTableOutput>> finalFuture = SettableFuture.create();
-
- class CallBackImpl implements FutureCallback<RpcResult<List<MultipartReply>>> {
- @Override
- public void onSuccess(final RpcResult<List<MultipartReply>> result) {
-
- if (result.isSuccessful()) {
- final List<MultipartReply> multipartReplies = result.getResult();
- if (multipartReplies.isEmpty()) {
- LOG.debug("Multipart reply to table features request shouldn't be empty list.");
- finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed()
- .withError(ErrorType.RPC, "Multipart reply list is empty.").build());
- } else {
- final Long xid = multipartReplies.get(0).getXid();
- LOG.debug(
- "OnSuccess, rpc result successful, multipart response for rpc update-table with xid {} obtained.",
- xid);
- final UpdateTableOutputBuilder updateTableOutputBuilder = new UpdateTableOutputBuilder();
- updateTableOutputBuilder.setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
- finalFuture.set(RpcResultBuilder.success(updateTableOutputBuilder.build()).build());
- try {
- writeResponseToOperationalDatastore(multipartReplies);
- } catch (Exception e) {
- LOG.warn("Not able to write to operational datastore: {}", e.getMessage());
- }
- }
- } else {
- LOG.debug("OnSuccess, rpc result unsuccessful, multipart response for rpc update-table was unsuccessful.");
- finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed().withRpcErrors(result.getErrors())
- .build());
- }
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.error("Failure multipart response for table features request. Exception: {}", t);
- finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed()
- .withError(ErrorType.RPC, "Future error", t).build());
- }
- }
-
- Futures.addCallback(multipartFuture, new CallBackImpl());
-
- return finalFuture;
- }
-
- /**
- * @param multipartReplies
- */
- private void writeResponseToOperationalDatastore(final List<MultipartReply> multipartReplies) throws Exception {
-
- final List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures> salTableFeatures = convertToSalTableFeatures(multipartReplies);
-
- final InstanceIdentifier<FlowCapableNode> flowCapableNodeII = InstanceIdentifier.create(Nodes.class)
- .child(Node.class, new NodeKey(getDeviceInfo().getNodeId())).augmentation(FlowCapableNode.class);
- for (final org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures tableFeatureData : salTableFeatures) {
- final Short tableId = tableFeatureData.getTableId();
- final KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures, TableFeaturesKey> tableFeaturesII = flowCapableNodeII
- .child(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures.class,
- new TableFeaturesKey(tableId));
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableFeaturesII,
- tableFeatureData);
- }
-
- txFacade.submitTransaction();
- }
-
- protected List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures> convertToSalTableFeatures(
- final List<MultipartReply> multipartReplies) {
- final List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures> salTableFeaturesAll = new ArrayList<>();
- for (final MultipartReply multipartReply : multipartReplies) {
- if (multipartReply.getType().equals(MultipartType.OFPMPTABLEFEATURES)) {
- final MultipartReplyBody multipartReplyBody = multipartReply.getMultipartReplyBody();
- if (multipartReplyBody instanceof MultipartReplyTableFeaturesCase) {
- final MultipartReplyTableFeaturesCase tableFeaturesCase = ((MultipartReplyTableFeaturesCase) multipartReplyBody);
- final MultipartReplyTableFeatures salTableFeatures = tableFeaturesCase
- .getMultipartReplyTableFeatures();
-
- final Optional<List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures>> salTableFeaturesPartial =
- convertorExecutor.convert(salTableFeatures, data);
-
- if (salTableFeaturesPartial.isPresent()) {
- salTableFeaturesAll.addAll(salTableFeaturesPartial.get());
- }
-
- LOG.debug("TableFeature {} for xid {}.", salTableFeatures, multipartReply.getXid());
- }
- }
- }
- return salTableFeaturesAll;
- }
-
- private MultipartRequestInputBuilder createMultipartHeader(final MultipartType multipart, final Long xid) {
- final MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder();
- mprInput.setType(multipart);
- mprInput.setVersion(getVersion());
- mprInput.setXid(xid);
- mprInput.setFlags(new MultipartRequestFlags(false));
- return mprInput;
- }
-
- @Override
- protected OfHeader buildRequest(final Xid xid, final UpdateTableInput input) throws ServiceException {
- final MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
- final MultipartRequestTableFeaturesBuilder requestBuilder = new MultipartRequestTableFeaturesBuilder();
-
- final Optional<List<TableFeatures>> ofTableFeatureList = convertorExecutor.convert(input.getUpdatedTable(), data);
- requestBuilder.setTableFeatures(ofTableFeatureList.orElse(Collections.emptyList()));
- caseBuilder.setMultipartRequestTableFeatures(requestBuilder.build());
-
- // Set request body to main multipart request
- final MultipartRequestInputBuilder mprInput = createMultipartHeader(MultipartType.OFPMPTABLEFEATURES,
- xid.getValue());
- mprInput.setMultipartRequestBody(caseBuilder.build());
-
- return mprInput.build();
- }
-}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-final class SimpleRequestCallback<T extends DataObject> extends AbstractRequestCallback<T> {
+public final class SimpleRequestCallback<T extends DataObject> extends AbstractRequestCallback<T> {
private static final Logger LOG = LoggerFactory.getLogger(SimpleRequestCallback.class);
private final Class<T> clazz;
private SimpleRequestCallback(final RequestContext<T> context, final Class<?> requestType, final MessageSpy spy, final Class<T> clazz) {
- super(context, requestType, spy);
+ super(context, requestType, spy, null);
this.clazz = Preconditions.checkNotNull(clazz);
}
- static <T extends DataObject> FutureCallback<OfHeader> create(final RequestContext<T> context, final Class<?> requestType, final MessageSpy spy, final Class<T> clazz) {
+ public static <T extends DataObject> FutureCallback<OfHeader> create(final RequestContext<T> context, final Class<?> requestType, final MessageSpy spy, final Class<T> clazz) {
return new SimpleRequestCallback<>(context, requestType, spy, clazz);
}
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-final class VoidRequestCallback extends AbstractRequestCallback<Void> {
+public final class VoidRequestCallback extends AbstractRequestCallback<Void> {
private static final RpcResult<Void> SUCCESS = RpcResultBuilder.<Void>success().build();
- VoidRequestCallback(final RequestContext<Void> context, final Class<?> requestType, final MessageSpy spy) {
- super(context, requestType, spy);
+ public VoidRequestCallback(final RequestContext<Void> context, final Class<?> requestType, final MessageSpy spy) {
+ super(context, requestType, spy, null);
}
@Override
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.multilayer;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
+import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
+import org.opendaylight.openflowplugin.impl.services.AbstractAggregateFlowMultipartService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.aggregate.flow.statistics.from.flow.table._for.given.match.output.AggregatedFlowStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+public class MultiLayerAggregateFlowMultipartService extends AbstractAggregateFlowMultipartService<MultipartReply> {
+
+ private final TranslatorLibrary translatorLibrary;
+
+ public MultiLayerAggregateFlowMultipartService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final TranslatorLibrary translatorLibrary) {
+ super(requestContextStack, deviceContext, convertorExecutor);
+ this.translatorLibrary = translatorLibrary;
+ }
+
+ @Override
+ public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> handleAndReply(final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
+ return Futures.transform(handleServiceCall(input),
+ (Function<RpcResult<List<MultipartReply>>, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>>) result -> {
+ if (Preconditions.checkNotNull(result).isSuccessful()) {
+ final MessageTranslator<MultipartReply, AggregatedFlowStatistics> messageTranslator = translatorLibrary
+ .lookupTranslator(new TranslatorKey(getVersion(), MultipartReplyAggregateCase.class.getName()));
+
+ return RpcResultBuilder
+ .success(new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder()
+ .setAggregatedFlowStatistics(result
+ .getResult()
+ .stream()
+ .map(multipartReply -> messageTranslator
+ .translate(multipartReply, getDeviceInfo(), null))
+ .collect(Collectors.toList())))
+ .build();
+ }
+
+ return RpcResultBuilder
+ .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>failed()
+ .withRpcErrors(result.getErrors())
+ .build();
+ });
+ }
+
+}
/*
- * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.multilayer;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
import java.util.ArrayList;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.Future;
-
import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
-import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava;
-import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
-import org.opendaylight.openflowplugin.extension.api.exception.ConverterNotFoundException;
import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SalExperimenterMpMessageService;
+import org.opendaylight.openflowplugin.impl.services.AbstractExperimenterMultipartService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.send.experimenter.mp.request.output.ExperimenterCoreMessageItem;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.send.experimenter.mp.request.output.ExperimenterCoreMessageItemBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
+public class MultiLayerExperimenterMultipartService extends AbstractExperimenterMultipartService<MultipartReply> {
-public class SalExperimenterMpMessageServiceImpl extends AbstractMultipartService<SendExperimenterMpRequestInput> implements SalExperimenterMpMessageService {
- private final ExtensionConverterProvider extensionConverterProvider;
- private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(SalExperimenterMpMessageServiceImpl.class);
+ private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(MultiLayerExperimenterMultipartService.class);
- public SalExperimenterMpMessageServiceImpl(final RequestContextStack requestContextStack,
- final DeviceContext deviceContext,
- final ExtensionConverterProvider extensionConverterProvider) {
- super(requestContextStack, deviceContext);
- this.extensionConverterProvider = extensionConverterProvider;
+ public MultiLayerExperimenterMultipartService(RequestContextStack requestContextStack, DeviceContext deviceContext,
+ ExtensionConverterProvider extensionConverterProvider) {
+ super(requestContextStack, deviceContext, extensionConverterProvider);
}
@Override
- public Future<RpcResult<SendExperimenterMpRequestOutput>> sendExperimenterMpRequest(SendExperimenterMpRequestInput input) {
+ @SuppressWarnings("unchecked")
+ public Future<RpcResult<SendExperimenterMpRequestOutput>> handleAndReply(SendExperimenterMpRequestInput input) {
final ListenableFuture<RpcResult<List<MultipartReply>>> multipartFuture = handleServiceCall(input);
final SettableFuture<RpcResult<SendExperimenterMpRequestOutput>> finalFuture = SettableFuture.create();
getVersion(),
(Class<? extends ExperimenterDataOfChoice>) vendorData.getImplementedInterface());
final ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath> messageConverter =
- extensionConverterProvider.getMessageConverter(key);
+ getExtensionConverterProvider().getMessageConverter(key);
if (messageConverter == null) {
LOG.warn("Custom converter for {}[OF:{}] not found",
vendorData.getImplementedInterface(),
return finalFuture;
}
- @Override
- @SuppressWarnings("unchecked")
- protected OfHeader buildRequest(Xid xid, SendExperimenterMpRequestInput input) throws ServiceException {
- final TypeVersionKey key = new TypeVersionKey(
- input.getExperimenterMessageOfChoice().getImplementedInterface(),
- getVersion());
-
- final ConvertorMessageToOFJava<ExperimenterMessageOfChoice, ExperimenterDataOfChoice> messageConverter =
- extensionConverterProvider.getMessageConverter(key);
-
- if (Objects.isNull(messageConverter)) {
- throw new ServiceException(new ConverterNotFoundException(key.toString()));
- }
-
- try {
- return RequestInputUtils
- .createMultipartHeader(MultipartType.OFPMPEXPERIMENTER, xid.getValue(), getVersion())
- .setMultipartRequestBody(new MultipartRequestExperimenterCaseBuilder()
- .setMultipartRequestExperimenter(new MultipartRequestExperimenterBuilder()
- .setExperimenter(messageConverter.getExperimenterId())
- .setExpType(messageConverter.getType())
- .setExperimenterDataOfChoice(messageConverter
- .convert(input.getExperimenterMessageOfChoice()))
- .build())
- .build())
- .build();
- } catch (final ConversionException e) {
- throw new ServiceException(e);
- }
- }
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.multilayer;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
+import java.util.Optional;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestOnTheFlyCallback;
+import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+
+public class MultiLayerFlowMultipartRequestOnTheFlyCallback<T extends OfHeader> extends AbstractMultipartRequestOnTheFlyCallback<T> {
+
+ private final ConvertorExecutor convertorExecutor;
+ private final DeviceInfo deviceInfo;
+ private boolean virgin = true;
+
+ public MultiLayerFlowMultipartRequestOnTheFlyCallback(final RequestContext<List<T>> context,
+ final Class<?> requestType,
+ final DeviceContext deviceContext,
+ final EventIdentifier eventIdentifier,
+ final MultipartWriterProvider statisticsWriterProvider,
+ final ConvertorExecutor convertorExecutor) {
+ super(context, requestType, deviceContext, eventIdentifier, statisticsWriterProvider);
+ this.convertorExecutor = convertorExecutor;
+ deviceInfo = deviceContext.getDeviceInfo();
+ }
+
+ @Override
+ protected boolean isMultipart(OfHeader result) {
+ return result instanceof MultipartReply
+ && MultipartReply.class.cast(result).getType().equals(getMultipartType());
+ }
+
+ @Override
+ protected boolean isReqMore(T result) {
+ return MultipartReply.class.cast(result).getFlags().isOFPMPFREQMORE();
+ }
+
+ @Override
+ protected MultipartType getMultipartType() {
+ return MultipartType.OFPMPFLOW;
+ }
+
+ @Override
+ protected ListenableFuture<Optional<? extends MultipartReplyBody>> processStatistics(T result) {
+ final ListenableFuture<Optional<? extends MultipartReplyBody>> future = Futures.transform(
+ StatisticsGatheringUtils.deleteAllKnownFlows(
+ getTxFacade(),
+ deviceInfo
+ .getNodeInstanceIdentifier()
+ .augmentation(FlowCapableNode.class),
+ !virgin),
+ (Function<Void, Optional<? extends MultipartReplyBody>>) input -> MultipartReplyTranslatorUtil
+ .translate(result, deviceInfo, convertorExecutor, null));
+
+ if (virgin) {
+ virgin = false;
+ }
+
+ return future;
+ }
+
+}
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.multilayer;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-final class FlowService<O extends DataObject> extends AbstractSimpleService<FlowModInputBuilder, O> {
+public final class MultiLayerFlowService<O extends DataObject> extends AbstractSimpleService<FlowModInputBuilder, O> {
private final ConvertorExecutor convertorExecutor;
private final VersionDatapathIdConvertorData data;
- protected FlowService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<O> clazz, final ConvertorExecutor convertorExecutor) {
+ public MultiLayerFlowService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<O> clazz, final ConvertorExecutor convertorExecutor) {
super(requestContextStack, deviceContext, clazz);
this.convertorExecutor = convertorExecutor;
data = new VersionDatapathIdConvertorData(getVersion());
return input.build();
}
- List<FlowModInputBuilder> toFlowModInputs(final Flow input) {
+ public List<FlowModInputBuilder> toFlowModInputs(final Flow input) {
final Optional<List<FlowModInputBuilder>> flowModInputBuilders = convertorExecutor.convert(input, data);
return flowModInputBuilders.orElse(Collections.emptyList());
}
- ListenableFuture<RpcResult<O>> processFlowModInputBuilders(final List<FlowModInputBuilder> ofFlowModInputs) {
+ public ListenableFuture<RpcResult<O>> processFlowModInputBuilders(final List<FlowModInputBuilder> ofFlowModInputs) {
final List<ListenableFuture<RpcResult<O>>> partialFutures = new ArrayList<>(ofFlowModInputs.size());
for (final FlowModInputBuilder flowModInputBuilder : ofFlowModInputs) {
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.multilayer;
import java.util.Optional;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.binding.DataObject;
-final class GroupService<I extends Group, O extends DataObject> extends AbstractSimpleService<I, O> {
+public final class MultiLayerGroupService<I extends Group, O extends DataObject> extends AbstractSimpleService<I, O> {
private final ConvertorExecutor convertorExecutor;
private final VersionDatapathIdConvertorData data;
- GroupService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<O> clazz, final ConvertorExecutor convertorExecutor) {
+ public MultiLayerGroupService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<O> clazz, final ConvertorExecutor convertorExecutor) {
super(requestContextStack, deviceContext, clazz);
this.convertorExecutor = convertorExecutor;
data = new VersionDatapathIdConvertorData(getVersion());
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.multilayer;
import java.util.Optional;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.binding.DataObject;
-final class MeterService<I extends Meter, O extends DataObject> extends AbstractSimpleService<I, O> {
+public final class MultiLayerMeterService<I extends Meter, O extends DataObject> extends AbstractSimpleService<I, O> {
private final ConvertorExecutor convertorExecutor;
private final VersionConvertorData data;
- MeterService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<O> clazz, final ConvertorExecutor convertorExecutor) {
+ public MultiLayerMeterService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<O> clazz, final ConvertorExecutor convertorExecutor) {
super(requestContextStack, deviceContext, clazz);
this.convertorExecutor = convertorExecutor;
data = new VersionConvertorData(getVersion());
meterModInputBuilder.setXid(xid.getValue());
return meterModInputBuilder.build();
}
-}
\ No newline at end of file
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.multilayer;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.services.AbstractMultipartCollectorService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+
+public class MultiLayerMultipartCollectorService extends AbstractMultipartCollectorService<MultipartReply> {
+
+ public MultiLayerMultipartCollectorService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
+ super(requestContextStack, deviceContext);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.multilayer;
+
+import java.util.List;
+import java.util.Objects;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestCallback;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+
+public class MultiLayerMultipartRequestCallback<T extends OfHeader> extends AbstractMultipartRequestCallback<T> {
+
+ public MultiLayerMultipartRequestCallback(RequestContext<List<T>> context, Class<?> requestType, DeviceContext deviceContext, EventIdentifier eventIdentifier) {
+ super(context, requestType, deviceContext, eventIdentifier);
+ }
+
+ @Override
+ protected boolean isMultipart(OfHeader result) {
+ return result instanceof MultipartReply;
+ }
+
+ @Override
+ protected boolean isReqMore(T result) {
+ final MultipartRequestFlags flags = MultipartReply.class.cast(result).getFlags();
+ return Objects.nonNull(flags) && flags.isOFPMPFREQMORE();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.multilayer;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.Future;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.services.AbstractTableMultipartService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MultiLayerTableMultipartService extends AbstractTableMultipartService<MultipartReply> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MultiLayerTableMultipartService.class);
+
+ public MultiLayerTableMultipartService(RequestContextStack requestContextStack,
+ DeviceContext deviceContext,
+ ConvertorExecutor convertorExecutor,
+ MultipartWriterProvider multipartWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, multipartWriterProvider);
+ }
+
+ @Override
+ public Future<RpcResult<UpdateTableOutput>> handleAndReply(UpdateTableInput input) {
+ final ListenableFuture<RpcResult<List<MultipartReply>>> multipartFuture = handleServiceCall(input);
+ final SettableFuture<RpcResult<UpdateTableOutput>> finalFuture = SettableFuture.create();
+
+ class CallBackImpl implements FutureCallback<RpcResult<List<MultipartReply>>> {
+ @Override
+ public void onSuccess(final RpcResult<List<MultipartReply>> result) {
+
+ if (result.isSuccessful()) {
+ final List<MultipartReply> multipartReplies = result.getResult();
+ if (multipartReplies.isEmpty()) {
+ LOG.debug("Multipart reply to table features request shouldn't be empty list.");
+ finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed()
+ .withError(ErrorType.RPC, "Multipart reply list is empty.").build());
+ } else {
+ final Long xid = multipartReplies.get(0).getXid();
+ LOG.debug(
+ "OnSuccess, rpc result successful, multipart response for rpc update-table with xid {} obtained.",
+ xid);
+ final UpdateTableOutputBuilder updateTableOutputBuilder = new UpdateTableOutputBuilder();
+ updateTableOutputBuilder.setTransactionId(new TransactionId(BigInteger.valueOf(xid)));
+ finalFuture.set(RpcResultBuilder.success(updateTableOutputBuilder.build()).build());
+ try {
+ storeStatistics(convertToSalTableFeatures(multipartReplies));
+ } catch (Exception e) {
+ LOG.warn("Not able to write to operational datastore: {}", e.getMessage());
+ }
+ }
+ } else {
+ LOG.debug("OnSuccess, rpc result unsuccessful, multipart response for rpc update-table was unsuccessful.");
+ finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed().withRpcErrors(result.getErrors())
+ .build());
+ }
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ LOG.error("Failure multipart response for table features request. Exception: {}", t);
+ finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed()
+ .withError(ErrorType.RPC, "Future error", t).build());
+ }
+ }
+
+ Futures.addCallback(multipartFuture, new CallBackImpl());
+
+ return finalFuture;
+ }
+
+ protected List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures> convertToSalTableFeatures(
+ final List<MultipartReply> multipartReplies) {
+ final List<org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures> salTableFeaturesAll = new ArrayList<>();
+ for (final MultipartReply multipartReply : multipartReplies) {
+ if (multipartReply.getType().equals(MultipartType.OFPMPTABLEFEATURES)) {
+ final MultipartReplyBody multipartReplyBody = multipartReply.getMultipartReplyBody();
+ if (multipartReplyBody instanceof MultipartReplyTableFeaturesCase) {
+ final MultipartReplyTableFeaturesCase tableFeaturesCase = ((MultipartReplyTableFeaturesCase) multipartReplyBody);
+ final MultipartReplyTableFeatures salTableFeatures = tableFeaturesCase
+ .getMultipartReplyTableFeatures();
+
+ final Optional<List<TableFeatures>> salTableFeaturesPartial =
+ getConvertorExecutor().convert(salTableFeatures, getData());
+
+ salTableFeaturesPartial.ifPresent(salTableFeaturesAll::addAll);
+
+ LOG.debug("TableFeature {} for xid {}.", salTableFeatures, multipartReply.getXid());
+ }
+ }
+ }
+
+ return salTableFeaturesAll;
+ }
+}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractVoidService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.NodeConfigService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfigInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfigOutput;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import java.util.Optional;
import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractVoidService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import javax.annotation.Nullable;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.services.EchoService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SalEchoService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoOutput;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
import org.opendaylight.openflowplugin.extension.api.exception.ConverterNotFoundException;
+import org.opendaylight.openflowplugin.impl.services.AbstractVoidService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SalExperimenterMessageService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenterInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInputBuilder;
--- /dev/null
+/*
+ * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.sal;
+
+import java.util.concurrent.Future;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerExperimenterMultipartService;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerExperimenterMultipartService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SalExperimenterMpMessageService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class SalExperimenterMpMessageServiceImpl implements SalExperimenterMpMessageService {
+ private final MultiLayerExperimenterMultipartService multiLayerService;
+ private final SingleLayerExperimenterMultipartService singleLayerService;
+
+ public SalExperimenterMpMessageServiceImpl(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ExtensionConverterProvider extensionConverterProvider) {
+ this.singleLayerService = new SingleLayerExperimenterMultipartService(requestContextStack, deviceContext,
+ extensionConverterProvider);
+ this.multiLayerService = new MultiLayerExperimenterMultipartService(requestContextStack, deviceContext,
+ extensionConverterProvider);
+ }
+
+ @Override
+ public Future<RpcResult<SendExperimenterMpRequestOutput>> sendExperimenterMpRequest(SendExperimenterMpRequestInput input) {
+ return singleLayerService.canUseSingleLayerSerialization()
+ ? singleLayerService.handleAndReply(input)
+ : multiLayerService.handleAndReply(input);
+ }
+
+}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.FutureCallback;
import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
import org.opendaylight.openflowplugin.impl.registry.flow.FlowDescriptorFactory;
import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerFlowService;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerFlowService;
import org.opendaylight.openflowplugin.impl.util.ErrorUtil;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil;
public class SalFlowServiceImpl implements SalFlowService, ItemLifeCycleSource {
private static final Logger LOG = LoggerFactory.getLogger(SalFlowServiceImpl.class);
- private final FlowService<UpdateFlowOutput> flowUpdate;
- private final FlowService<AddFlowOutput> flowAdd;
- private final FlowService<RemoveFlowOutput> flowRemove;
- private final FlowMessageService<AddFlowOutput> flowAddMessage;
- private final FlowMessageService<UpdateFlowOutput> flowUpdateMessage;
- private final FlowMessageService<RemoveFlowOutput> flowRemoveMessage;
+ private final MultiLayerFlowService<UpdateFlowOutput> flowUpdate;
+ private final MultiLayerFlowService<AddFlowOutput> flowAdd;
+ private final MultiLayerFlowService<RemoveFlowOutput> flowRemove;
+ private final SingleLayerFlowService<AddFlowOutput> flowAddMessage;
+ private final SingleLayerFlowService<UpdateFlowOutput> flowUpdateMessage;
+ private final SingleLayerFlowService<RemoveFlowOutput> flowRemoveMessage;
private final DeviceContext deviceContext;
private ItemLifecycleListener itemLifecycleListener;
public SalFlowServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
this.deviceContext = deviceContext;
- flowRemove = new FlowService<>(requestContextStack, deviceContext, RemoveFlowOutput.class, convertorExecutor);
- flowAdd = new FlowService<>(requestContextStack, deviceContext, AddFlowOutput.class, convertorExecutor);
- flowUpdate = new FlowService<>(requestContextStack, deviceContext, UpdateFlowOutput.class, convertorExecutor);
- flowAddMessage = new FlowMessageService<>(requestContextStack, deviceContext, AddFlowOutput.class);
- flowUpdateMessage = new FlowMessageService<>(requestContextStack, deviceContext, UpdateFlowOutput.class);
- flowRemoveMessage= new FlowMessageService<>(requestContextStack, deviceContext, RemoveFlowOutput.class);
+ flowRemove = new MultiLayerFlowService<>(requestContextStack, deviceContext, RemoveFlowOutput.class, convertorExecutor);
+ flowAdd = new MultiLayerFlowService<>(requestContextStack, deviceContext, AddFlowOutput.class, convertorExecutor);
+ flowUpdate = new MultiLayerFlowService<>(requestContextStack, deviceContext, UpdateFlowOutput.class, convertorExecutor);
+ flowAddMessage = new SingleLayerFlowService<>(requestContextStack, deviceContext, AddFlowOutput.class);
+ flowUpdateMessage = new SingleLayerFlowService<>(requestContextStack, deviceContext, UpdateFlowOutput.class);
+ flowRemoveMessage= new SingleLayerFlowService<>(requestContextStack, deviceContext, RemoveFlowOutput.class);
}
@Override
final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceContext.getDeviceInfo().getVersion(), input);
final ListenableFuture<RpcResult<AddFlowOutput>> future;
- if (flowAddMessage.isSupported()) {
+ if (flowAddMessage.canUseSingleLayerSerialization()) {
future = flowAddMessage.handleServiceCall(input);
Futures.addCallback(future, new AddFlowCallback(input, flowRegistryKey));
} else {
public Future<RpcResult<RemoveFlowOutput>> removeFlow(final RemoveFlowInput input) {
final ListenableFuture<RpcResult<RemoveFlowOutput>> future;
- if (flowRemoveMessage.isSupported()) {
+ if (flowRemoveMessage.canUseSingleLayerSerialization()) {
future = flowRemoveMessage.handleServiceCall(input);
Futures.addCallback(future, new RemoveFlowCallback(input));
final List<FlowModInputBuilder> ofFlowModInputs;
ListenableFuture<RpcResult<UpdateFlowOutput>> future;
- if (flowUpdateMessage.isSupported()) {
+ if (flowUpdateMessage.canUseSingleLayerSerialization()) {
if (!FlowCreatorUtil.canModifyFlow(original, updated, flowUpdateMessage.getVersion())) {
final SettableFuture<RpcResult<UpdateFlowOutput>> objectSettableFuture = SettableFuture.create();
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.Futures;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource;
import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerGroupService;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerGroupService;
import org.opendaylight.openflowplugin.impl.util.ErrorUtil;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
public class SalGroupServiceImpl implements SalGroupService, ItemLifeCycleSource {
private static final Logger LOG = LoggerFactory.getLogger(SalGroupServiceImpl.class);
- private final GroupService<AddGroupInput, AddGroupOutput> addGroup;
- private final GroupService<Group, UpdateGroupOutput> updateGroup;
- private final GroupService<RemoveGroupInput, RemoveGroupOutput> removeGroup;
- private final GroupMessageService<AddGroupOutput> addGroupMessage;
- private final GroupMessageService<UpdateGroupOutput> updateGroupMessage;
- private final GroupMessageService<RemoveGroupOutput> removeGroupMessage;
+ private final MultiLayerGroupService<AddGroupInput, AddGroupOutput> addGroup;
+ private final MultiLayerGroupService<Group, UpdateGroupOutput> updateGroup;
+ private final MultiLayerGroupService<RemoveGroupInput, RemoveGroupOutput> removeGroup;
+ private final SingleLayerGroupService<AddGroupOutput> addGroupMessage;
+ private final SingleLayerGroupService<UpdateGroupOutput> updateGroupMessage;
+ private final SingleLayerGroupService<RemoveGroupOutput> removeGroupMessage;
private final DeviceContext deviceContext;
private ItemLifecycleListener itemLifecycleListener;
public SalGroupServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
this.deviceContext = deviceContext;
- addGroup = new GroupService<>(requestContextStack, deviceContext, AddGroupOutput.class, convertorExecutor);
- updateGroup = new GroupService<>(requestContextStack, deviceContext, UpdateGroupOutput.class, convertorExecutor);
- removeGroup = new GroupService<>(requestContextStack, deviceContext, RemoveGroupOutput.class, convertorExecutor);
+ addGroup = new MultiLayerGroupService<>(requestContextStack, deviceContext, AddGroupOutput.class, convertorExecutor);
+ updateGroup = new MultiLayerGroupService<>(requestContextStack, deviceContext, UpdateGroupOutput.class, convertorExecutor);
+ removeGroup = new MultiLayerGroupService<>(requestContextStack, deviceContext, RemoveGroupOutput.class, convertorExecutor);
- addGroupMessage = new GroupMessageService<>(requestContextStack, deviceContext, AddGroupOutput.class);
- updateGroupMessage = new GroupMessageService<>(requestContextStack, deviceContext, UpdateGroupOutput.class);
- removeGroupMessage = new GroupMessageService<>(requestContextStack, deviceContext, RemoveGroupOutput.class);
+ addGroupMessage = new SingleLayerGroupService<>(requestContextStack, deviceContext, AddGroupOutput.class);
+ updateGroupMessage = new SingleLayerGroupService<>(requestContextStack, deviceContext, UpdateGroupOutput.class);
+ removeGroupMessage = new SingleLayerGroupService<>(requestContextStack, deviceContext, RemoveGroupOutput.class);
}
@Override
@Override
public Future<RpcResult<AddGroupOutput>> addGroup(final AddGroupInput input) {
- final ListenableFuture<RpcResult<AddGroupOutput>> resultFuture = addGroupMessage.isSupported()
+ final ListenableFuture<RpcResult<AddGroupOutput>> resultFuture = addGroupMessage.canUseSingleLayerSerialization()
? addGroupMessage.handleServiceCall(input)
: addGroup.handleServiceCall(input);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Group add with id={} failed, errors={}", input.getGroupId().getValue(),
- ErrorUtil.errorsToString(result.getErrors()));
+ ErrorUtil.errorsToString(result.getErrors()));
}
}
}
@Override
public Future<RpcResult<UpdateGroupOutput>> updateGroup(final UpdateGroupInput input) {
- final ListenableFuture<RpcResult<UpdateGroupOutput>> resultFuture = updateGroupMessage.isSupported()
+ final ListenableFuture<RpcResult<UpdateGroupOutput>> resultFuture = updateGroupMessage.canUseSingleLayerSerialization()
? updateGroupMessage.handleServiceCall(input.getUpdatedGroup())
: updateGroup.handleServiceCall(input.getUpdatedGroup());
Futures.addCallback(resultFuture, new FutureCallback<RpcResult<UpdateGroupOutput>>() {
@Override
- public void onSuccess(@Nullable RpcResult<UpdateGroupOutput> result) {
+ public void onSuccess(RpcResult<UpdateGroupOutput> result) {
if (result.isSuccessful()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Group update with original id={} finished without error",
- input.getOriginalGroup().getGroupId().getValue());
+ input.getOriginalGroup().getGroupId().getValue());
}
removeIfNecessaryFromDS(input.getOriginalGroup().getGroupId());
addIfNecessaryToDS(input.getUpdatedGroup().getGroupId(), input.getUpdatedGroup());
} else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Group update with original id={} failed, errors={}",
- input.getOriginalGroup().getGroupId(), ErrorUtil.errorsToString(result.getErrors()));
- }
+ LOG.warn("Group update with original id={} failed, errors={}",
+ input.getOriginalGroup().getGroupId(), ErrorUtil.errorsToString(result.getErrors()));
+ LOG.debug("Group input={}", input.getUpdatedGroup());
}
}
@Override
public Future<RpcResult<RemoveGroupOutput>> removeGroup(final RemoveGroupInput input) {
- final ListenableFuture<RpcResult<RemoveGroupOutput>> resultFuture = removeGroupMessage.isSupported()
+ final ListenableFuture<RpcResult<RemoveGroupOutput>> resultFuture = removeGroupMessage.canUseSingleLayerSerialization()
? removeGroupMessage.handleServiceCall(input)
: removeGroup.handleServiceCall(input);
Futures.addCallback(resultFuture, new FutureCallback<RpcResult<RemoveGroupOutput>>() {
@Override
- public void onSuccess(@Nullable RpcResult<RemoveGroupOutput> result) {
+ public void onSuccess(RpcResult<RemoveGroupOutput> result) {
if (result.isSuccessful()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Group remove with id={} finished without error", input.getGroupId().getValue());
removeGroup.getDeviceRegistry().getDeviceGroupRegistry().markToBeremoved(input.getGroupId());
removeIfNecessaryFromDS(input.getGroupId());
} else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Group remove with id={} failed, errors={}", input.getGroupId().getValue(),
- ErrorUtil.errorsToString(result.getErrors()));
- }
+ LOG.warn("Group remove with id={} failed, errors={}", input.getGroupId().getValue(),
+ ErrorUtil.errorsToString(result.getErrors()));
+ LOG.debug("Group input={}", input);
}
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource;
import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerMeterService;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMeterService;
import org.opendaylight.openflowplugin.impl.util.ErrorUtil;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
public class SalMeterServiceImpl implements SalMeterService, ItemLifeCycleSource {
private static final Logger LOG = LoggerFactory.getLogger(SalMeterServiceImpl.class);
- private final MeterService<AddMeterInput, AddMeterOutput> addMeter;
- private final MeterService<Meter, UpdateMeterOutput> updateMeter;
- private final MeterService<RemoveMeterInput, RemoveMeterOutput> removeMeter;
- private final MeterMessageService<AddMeterOutput> addMeterMessage;
- private final MeterMessageService<UpdateMeterOutput> updateMeterMessage;
- private final MeterMessageService<RemoveMeterOutput> removeMeterMessage;
+ private final MultiLayerMeterService<AddMeterInput, AddMeterOutput> addMeter;
+ private final MultiLayerMeterService<Meter, UpdateMeterOutput> updateMeter;
+ private final MultiLayerMeterService<RemoveMeterInput, RemoveMeterOutput> removeMeter;
+ private final SingleLayerMeterService<AddMeterOutput> addMeterMessage;
+ private final SingleLayerMeterService<UpdateMeterOutput> updateMeterMessage;
+ private final SingleLayerMeterService<RemoveMeterOutput> removeMeterMessage;
private ItemLifecycleListener itemLifecycleListener;
private final DeviceContext deviceContext;
public SalMeterServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
this.deviceContext = deviceContext;
- addMeter = new MeterService<>(requestContextStack, deviceContext, AddMeterOutput.class, convertorExecutor);
- updateMeter = new MeterService<>(requestContextStack, deviceContext, UpdateMeterOutput.class, convertorExecutor);
- removeMeter = new MeterService<>(requestContextStack, deviceContext, RemoveMeterOutput.class, convertorExecutor);
+ addMeter = new MultiLayerMeterService<>(requestContextStack, deviceContext, AddMeterOutput.class, convertorExecutor);
+ updateMeter = new MultiLayerMeterService<>(requestContextStack, deviceContext, UpdateMeterOutput.class, convertorExecutor);
+ removeMeter = new MultiLayerMeterService<>(requestContextStack, deviceContext, RemoveMeterOutput.class, convertorExecutor);
- addMeterMessage = new MeterMessageService<>(requestContextStack, deviceContext, AddMeterOutput.class);
- updateMeterMessage = new MeterMessageService<>(requestContextStack, deviceContext, UpdateMeterOutput.class);
- removeMeterMessage = new MeterMessageService<>(requestContextStack, deviceContext, RemoveMeterOutput.class);
+ addMeterMessage = new SingleLayerMeterService<>(requestContextStack, deviceContext, AddMeterOutput.class);
+ updateMeterMessage = new SingleLayerMeterService<>(requestContextStack, deviceContext, UpdateMeterOutput.class);
+ removeMeterMessage = new SingleLayerMeterService<>(requestContextStack, deviceContext, RemoveMeterOutput.class);
}
@Override
@Override
public Future<RpcResult<AddMeterOutput>> addMeter(final AddMeterInput input) {
- final ListenableFuture<RpcResult<AddMeterOutput>> resultFuture = addMeterMessage.isSupported()
+ final ListenableFuture<RpcResult<AddMeterOutput>> resultFuture = addMeterMessage.canUseSingleLayerSerialization()
? addMeterMessage.handleServiceCall(input)
: addMeter.handleServiceCall(input);
Futures.addCallback(resultFuture, new FutureCallback<RpcResult<AddMeterOutput>>() {
@Override
- public void onSuccess(@Nullable RpcResult<AddMeterOutput> result) {
+ public void onSuccess(RpcResult<AddMeterOutput> result) {
if (result.isSuccessful()) {
- if (LOG.isDebugEnabled()) {
+ if (LOG.isDebugEnabled()) {
LOG.debug("Meter add with id={} finished without error", input.getMeterId());
}
deviceContext.getDeviceMeterRegistry().store(input.getMeterId());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Meter add with id={} failed, errors={}", input.getMeterId(),
- ErrorUtil.errorsToString(result.getErrors()));
+ ErrorUtil.errorsToString(result.getErrors()));
}
}
}
@Override
public Future<RpcResult<UpdateMeterOutput>> updateMeter(final UpdateMeterInput input) {
- final ListenableFuture<RpcResult<UpdateMeterOutput>> resultFuture = updateMeterMessage.isSupported()
+ final ListenableFuture<RpcResult<UpdateMeterOutput>> resultFuture = updateMeterMessage.canUseSingleLayerSerialization()
? updateMeterMessage.handleServiceCall(input.getUpdatedMeter())
: updateMeter.handleServiceCall(input.getUpdatedMeter());
Futures.addCallback(resultFuture, new FutureCallback<RpcResult<UpdateMeterOutput>>() {
@Override
- public void onSuccess(@Nullable RpcResult<UpdateMeterOutput> result) {
+ public void onSuccess(RpcResult<UpdateMeterOutput> result) {
if (result.isSuccessful()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Meter update with id={} finished without error", input.getOriginalMeter().getMeterId());
addIfNecessaryToDS(input.getUpdatedMeter().getMeterId(),input.getUpdatedMeter());
}
} else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Meter update with id={} failed, errors={}", input.getOriginalMeter().getMeterId(),
+ LOG.warn("Meter update with id={} failed, errors={}", input.getOriginalMeter().getMeterId(),
ErrorUtil.errorsToString(result.getErrors()));
- }
+ LOG.debug("Meter input={}", input.getUpdatedMeter());
}
}
@Override
public Future<RpcResult<RemoveMeterOutput>> removeMeter(final RemoveMeterInput input) {
- removeMeter.getDeviceRegistry().getDeviceMeterRegistry().markToBeremoved(input.getMeterId());
- final ListenableFuture<RpcResult<RemoveMeterOutput>> resultFuture = removeMeterMessage.isSupported()
+ final ListenableFuture<RpcResult<RemoveMeterOutput>> resultFuture = removeMeterMessage.canUseSingleLayerSerialization()
? removeMeterMessage.handleServiceCall(input)
: removeMeter.handleServiceCall(input);
Futures.addCallback(resultFuture, new FutureCallback<RpcResult<RemoveMeterOutput>>() {
@Override
- public void onSuccess(@Nullable RpcResult<RemoveMeterOutput> result) {
+ public void onSuccess(RpcResult<RemoveMeterOutput> result) {
if (result.isSuccessful()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Meter remove with id={} finished without error", input.getMeterId());
}
+ removeMeter.getDeviceRegistry().getDeviceMeterRegistry().markToBeremoved(input.getMeterId());
removeIfNecessaryFromDS(input.getMeterId());
} else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Meter remove with id={} failed, errors={}", input.getMeterId(),
- ErrorUtil.errorsToString(result.getErrors()));
- }
+ LOG.warn("Meter remove with id={} failed, errors={}", input.getMeterId(),
+ ErrorUtil.errorsToString(result.getErrors()));
+ LOG.debug("Meter input={}", input);
}
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import java.util.Optional;
import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerPortService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
public final class SalPortServiceImpl extends AbstractSimpleService<UpdatePortInput, UpdatePortOutput> implements SalPortService {
private final ConvertorExecutor convertorExecutor;
private final VersionConvertorData data;
- private final PortMessageService<UpdatePortOutput> portMessage;
+ private final SingleLayerPortService<UpdatePortOutput> portMessage;
public SalPortServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
super(requestContextStack, deviceContext, UpdatePortOutput.class);
this.convertorExecutor = convertorExecutor;
data = new VersionConvertorData(getVersion());
- portMessage = new PortMessageService<>(requestContextStack, deviceContext, UpdatePortOutput.class);
+ portMessage = new SingleLayerPortService<>(requestContextStack, deviceContext, UpdatePortOutput.class);
}
@Override
public Future<RpcResult<UpdatePortOutput>> updatePort(final UpdatePortInput input) {
- return portMessage.isSupported()
+ return portMessage.canUseSingleLayerSerialization()
? portMessage.handleServiceCall(getPortFromInput(input))
: handleServiceCall(input);
}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.AsyncFunction;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.impl.role.RoleChangeException;
+import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
+import org.opendaylight.openflowplugin.impl.services.RoleService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.role.service.rev150727.OfpRole;
return RpcResultBuilder.<SetRoleOutput> success().buildFuture();
}
- final SettableFuture<RpcResult<SetRoleOutput>> resultFuture = SettableFuture.<RpcResult<SetRoleOutput>> create();
+ final SettableFuture<RpcResult<SetRoleOutput>> resultFuture = SettableFuture.create();
repeaterForChangeRole(resultFuture, input, 0);
/* Add Callback for release Guard */
Futures.addCallback(resultFuture, new FutureCallback<RpcResult<SetRoleOutput>>() {
--- /dev/null
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.openflowplugin.impl.services.sal;
+
+import java.util.concurrent.Future;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerTableMultipartService;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerTableMultipartService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public final class SalTableServiceImpl implements SalTableService {
+
+ private final SingleLayerTableMultipartService singleLayerService;
+ private final MultiLayerTableMultipartService multiLayerService;
+
+ public SalTableServiceImpl(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider multipartWriterProvider) {
+ singleLayerService = new SingleLayerTableMultipartService(requestContextStack, deviceContext, convertorExecutor, multipartWriterProvider);
+ multiLayerService = new MultiLayerTableMultipartService(requestContextStack, deviceContext, convertorExecutor, multipartWriterProvider);
+ }
+
+ @Override
+ public Future<RpcResult<UpdateTableOutput>> updateTable(final UpdateTableInput input) {
+ return singleLayerService.canUseSingleLayerSerialization()
+ ? singleLayerService.handleAndReply(input)
+ : multiLayerService.handleAndReply(input);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
+
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.services.AbstractAggregateFlowMultipartService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.aggregate.flow.statistics.from.flow.table._for.given.match.output.AggregatedFlowStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowAggregateStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+
+public class SingleLayerAggregateFlowMultipartService
+ extends AbstractAggregateFlowMultipartService<MultipartReply> {
+
+ public SingleLayerAggregateFlowMultipartService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor) {
+ super(requestContextStack, deviceContext, convertorExecutor);
+ }
+
+ @Override
+ public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> handleAndReply(
+ final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
+ return Futures.transform(handleServiceCall(input),
+ (Function<RpcResult<List<MultipartReply>>, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>>) result -> {
+ if (Preconditions.checkNotNull(result).isSuccessful()) {
+ return RpcResultBuilder
+ .success(new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder()
+ .setAggregatedFlowStatistics(result
+ .getResult()
+ .stream()
+ .map(MultipartReply::getMultipartReplyBody)
+ .filter(MultipartReplyFlowAggregateStats.class::isInstance)
+ .map(multipartReplyBody ->
+ new AggregatedFlowStatisticsBuilder(MultipartReplyFlowAggregateStats.class
+ .cast(multipartReplyBody))
+ .build())
+ .collect(Collectors.toList())))
+ .build();
+ }
+
+ return RpcResultBuilder
+ .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>failed()
+ .withRpcErrors(result.getErrors())
+ .build();
+ });
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.SettableFuture;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.impl.services.AbstractExperimenterMultipartService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.send.experimenter.mp.request.output.ExperimenterCoreMessageItemBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.multipart.reply.multipart.reply.body.MultipartReplyExperimenter;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+
+public class SingleLayerExperimenterMultipartService extends AbstractExperimenterMultipartService<MultipartReply> {
+
+ private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(SingleLayerExperimenterMultipartService.class);
+
+ public SingleLayerExperimenterMultipartService(RequestContextStack requestContextStack, DeviceContext deviceContext,
+ ExtensionConverterProvider extensionConverterProvider) {
+ super(requestContextStack, deviceContext, extensionConverterProvider);
+ }
+
+ @Override
+ public Future<RpcResult<SendExperimenterMpRequestOutput>> handleAndReply(SendExperimenterMpRequestInput input) {
+ final SettableFuture<RpcResult<SendExperimenterMpRequestOutput>> future = SettableFuture.create();
+
+ Futures.addCallback(handleServiceCall(input), new FutureCallback<RpcResult<List<MultipartReply>>>() {
+ @Override
+ public void onSuccess(final RpcResult<List<MultipartReply>> result) {
+ if (result.isSuccessful()) {
+ future.set(RpcResultBuilder
+ .success(new SendExperimenterMpRequestOutputBuilder()
+ .setExperimenterCoreMessageItem(result
+ .getResult()
+ .stream()
+ .map(MultipartReply::getMultipartReplyBody)
+ .filter(MultipartReplyExperimenter.class::isInstance)
+ .map(experimenter -> new ExperimenterCoreMessageItemBuilder()
+ .setExperimenterMessageOfChoice(MultipartReplyExperimenter.class
+ .cast(experimenter)
+ .getExperimenterMessageOfChoice())
+ .build())
+ .collect(Collectors.toList()))
+ .build())
+ .build());
+ } else {
+ LOG.warn("OnSuccess, rpc result unsuccessful, multipart response for rpc sendExperimenterMpRequest was unsuccessful.");
+ future.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed().withRpcErrors(result.getErrors()).build());
+ }
+ }
+
+ @Override
+ public void onFailure(final Throwable t) {
+ LOG.warn("Failure multipart response for Experimenter-Mp request. Exception: {}", t);
+ future.set(RpcResultBuilder.<SendExperimenterMpRequestOutput>failed().withError(ErrorType.RPC, "Future error", t).build());
+ }
+ });
+
+ return future;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.List;
+import java.util.Optional;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestOnTheFlyCallback;
+import org.opendaylight.openflowplugin.impl.statistics.StatisticsGatheringUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+
+public class SingleLayerFlowMultipartRequestOnTheFlyCallback<T extends OfHeader> extends AbstractMultipartRequestOnTheFlyCallback<T> {
+
+ private final DeviceInfo deviceInfo;
+ private boolean virgin = true;
+
+ public SingleLayerFlowMultipartRequestOnTheFlyCallback(final RequestContext<List<T>> context, Class<?> requestType,
+ final DeviceContext deviceContext,
+ final EventIdentifier eventIdentifier,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(context, requestType, deviceContext, eventIdentifier, statisticsWriterProvider);
+ deviceInfo = deviceContext.getDeviceInfo();
+ }
+
+ @Override
+ protected boolean isMultipart(OfHeader result) {
+ return result instanceof MultipartReply
+ && MultipartReply.class.cast(result).getMultipartReplyBody() instanceof MultipartReplyFlowStats;
+ }
+
+ @Override
+ protected boolean isReqMore(T result) {
+ return MultipartReply.class.cast(result).isRequestMore();
+ }
+
+ @Override
+ protected MultipartType getMultipartType() {
+ return MultipartType.OFPMPFLOW;
+ }
+
+ @Override
+ protected ListenableFuture<Optional<? extends MultipartReplyBody>> processStatistics(T result) {
+ final ListenableFuture<Optional<? extends MultipartReplyBody>> future = Futures.transform(
+ StatisticsGatheringUtils.deleteAllKnownFlows(
+ getTxFacade(),
+ deviceInfo
+ .getNodeInstanceIdentifier()
+ .augmentation(FlowCapableNode.class),
+ !virgin),
+ (Function<Void, Optional<? extends MultipartReplyBody>>) input -> MultipartReplyTranslatorUtil
+ .translate(result, deviceInfo, null, null));
+
+ if (virgin) {
+ virgin = false;
+ }
+
+ return future;
+ }
+
+}
-/**
+/*
* Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
-import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSilentErrorService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
-final class FlowMessageService<O extends DataObject> extends AbstractMessageService<Flow, FlowMessageBuilder, O> {
- protected FlowMessageService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<O> clazz) {
+public final class SingleLayerFlowService<O extends DataObject> extends AbstractSilentErrorService<Flow, O> {
+ public SingleLayerFlowService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final Class<O> clazz) {
super(requestContextStack, deviceContext, clazz);
}
.build();
}
- @Override
- public boolean isSupported() {
- return super.isSupported() && getVersion() >= OFConstants.OFP_VERSION_1_3;
- }
-
}
-/**
+/*
* Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
-import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroup;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
-final class GroupMessageService<O extends DataObject> extends AbstractMessageService<Group, GroupMessageBuilder, O> {
+public final class SingleLayerGroupService<O extends DataObject> extends AbstractSimpleService<Group, O> {
- protected GroupMessageService(
- final RequestContextStack requestContextStack,
- final DeviceContext deviceContext,
- final Class<O> clazz) {
+ public SingleLayerGroupService(
+ final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final Class<O> clazz) {
super(requestContextStack, deviceContext, clazz);
}
final GroupMessageBuilder groupMessageBuilder = new GroupMessageBuilder(input);
final Class<? extends DataContainer> clazz = input.getImplementedInterface();
- if (clazz.equals(AddGroupInput.class)
- || clazz.equals(UpdatedGroup.class)) {
+ if (clazz.equals(AddGroupInput.class)) {
groupMessageBuilder.setCommand(GroupModCommand.OFPGCADD);
+ } else if (clazz.equals(UpdatedGroup.class)) {
+ groupMessageBuilder.setCommand(GroupModCommand.OFPGCMODIFY);
} else if (clazz.equals(RemoveGroupInput.class)
|| clazz.equals(OriginalGroup.class)) {
groupMessageBuilder.setCommand(GroupModCommand.OFPGCDELETE);
.build();
}
- @Override
- public boolean isSupported() {
- return super.isSupported() && getVersion() >= OFConstants.OFP_VERSION_1_3;
- }
-
}
-/**
+/*
* Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
-import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSilentErrorService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeter;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
-final class MeterMessageService<O extends DataObject> extends AbstractMessageService<Meter, MeterMessageBuilder, O> {
+public final class SingleLayerMeterService<O extends DataObject> extends AbstractSilentErrorService<Meter, O> {
- protected MeterMessageService(
- final RequestContextStack requestContextStack,
- final DeviceContext deviceContext,
- final Class<O> clazz) {
+ public SingleLayerMeterService(
+ final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final Class<O> clazz) {
super(requestContextStack, deviceContext, clazz);
}
@Override
protected OfHeader buildRequest(final Xid xid, final Meter input) throws ServiceException {
- final MeterMessageBuilder groupMessageBuilder = new MeterMessageBuilder(input);
+ final MeterMessageBuilder meterMessageBuilder = new MeterMessageBuilder(input);
final Class<? extends DataContainer> clazz = input.getImplementedInterface();
if (clazz.equals(AddMeterInput.class)
|| clazz.equals(UpdatedMeter.class)) {
- groupMessageBuilder.setCommand(MeterModCommand.OFPMCADD);
+ meterMessageBuilder.setCommand(MeterModCommand.OFPMCADD);
} else if (clazz.equals(RemoveMeterInput.class)
|| clazz.equals(OriginalMeter.class)) {
- groupMessageBuilder.setCommand(MeterModCommand.OFPMCDELETE);
+ meterMessageBuilder.setCommand(MeterModCommand.OFPMCDELETE);
}
- return groupMessageBuilder
+ return meterMessageBuilder
.setVersion(getVersion())
.setXid(xid.getValue())
.build();
}
- @Override
- public boolean isSupported() {
- return super.isSupported() && getVersion() >= OFConstants.OFP_VERSION_1_3;
- }
-
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.services.AbstractMultipartCollectorService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+
+public class SingleLayerMultipartCollectorService extends AbstractMultipartCollectorService<MultipartReply> {
+
+ public SingleLayerMultipartCollectorService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
+ super(requestContextStack, deviceContext);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
+
+import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestCallback;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+
+public class SingleLayerMultipartRequestCallback<T extends OfHeader> extends AbstractMultipartRequestCallback<T> {
+
+ public SingleLayerMultipartRequestCallback(RequestContext<List<T>> context, Class<?> requestType, DeviceContext deviceContext, EventIdentifier eventIdentifier) {
+ super(context, requestType, deviceContext, eventIdentifier);
+ }
+
+ @Override
+ protected boolean isMultipart(OfHeader result) {
+ return result instanceof MultipartReply;
+ }
+
+ @Override
+ protected boolean isReqMore(T result) {
+ return MultipartReply.class.cast(result).isRequestMore();
+ }
+
+}
-/**
+/*
* Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
-import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.AbstractSimpleService;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.CommonPort;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortMessageBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.binding.DataObject;
-final class PortMessageService<O extends DataObject> extends AbstractMessageService<CommonPort, PortMessageBuilder, O> {
+public final class SingleLayerPortService<O extends DataObject> extends AbstractSimpleService<CommonPort, O> {
- protected PortMessageService(
- final RequestContextStack requestContextStack,
- final DeviceContext deviceContext,
- final Class<O> clazz) {
+ public SingleLayerPortService(
+ final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final Class<O> clazz) {
super(requestContextStack, deviceContext, clazz);
}
.build();
}
- @Override
- public boolean isSupported() {
- return super.isSupported() && getVersion() >= OFConstants.OFP_VERSION_1_3;
- }
-
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.services.singlelayer;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.SettableFuture;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.services.AbstractTableMultipartService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.multipart.reply.multipart.reply.body.MultipartReplyTableFeatures;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SingleLayerTableMultipartService extends AbstractTableMultipartService<MultipartReply> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SingleLayerTableMultipartService.class);
+
+ public SingleLayerTableMultipartService(RequestContextStack requestContextStack,
+ DeviceContext deviceContext,
+ ConvertorExecutor convertorExecutor,
+ MultipartWriterProvider multipartWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, multipartWriterProvider);
+ }
+
+ @Override
+ public Future<RpcResult<UpdateTableOutput>> handleAndReply(UpdateTableInput input) {
+ final SettableFuture<RpcResult<UpdateTableOutput>> finalFuture = SettableFuture.create();
+
+ Futures.addCallback(handleServiceCall(input), new FutureCallback<RpcResult<List<MultipartReply>>>() {
+ @Override
+ public void onSuccess(final RpcResult<List<MultipartReply>> result) {
+ if (result.isSuccessful()) {
+ final List<MultipartReply> multipartReplies = result.getResult();
+ if (multipartReplies.isEmpty()) {
+ LOG.debug("Multipart reply to table features request shouldn't be empty list.");
+ finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed()
+ .withError(ErrorType.RPC, "Multipart reply list is empty.").build());
+ } else {
+ finalFuture.set(RpcResultBuilder
+ .success(new UpdateTableOutputBuilder()
+ .setTransactionId(new TransactionId(BigInteger.valueOf(multipartReplies.get(0).getXid())))
+ .build())
+ .build());
+
+ try {
+ storeStatistics(multipartReplies
+ .stream()
+ .map(MultipartReply::getMultipartReplyBody)
+ .filter(MultipartReplyTableFeatures.class::isInstance)
+ .flatMap(multipartReplyBody -> MultipartReplyTableFeatures.class
+ .cast(multipartReplyBody)
+ .getTableFeatures()
+ .stream())
+ .collect(Collectors.toList()));
+ } catch (Exception e) {
+ LOG.warn("Not able to write to operational datastore: {}", e.getMessage());
+ }
+ }
+ } else {
+ LOG.debug("OnSuccess, rpc result unsuccessful, multipart response for rpc update-table was unsuccessful.");
+ finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed().withRpcErrors(result.getErrors())
+ .build());
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ LOG.error("Failure multipart response for table features request. Exception: {}", t);
+ finalFuture.set(RpcResultBuilder.<UpdateTableOutput>failed()
+ .withError(ErrorType.RPC, "Future error", t).build());
+ }
+ });
+
+ return finalFuture;
+ }
+
+}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.util;
import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.util;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.util;
/**
* Exception thrown by {@link org.opendaylight.openflowplugin.impl.services.AbstractService#buildRequest(org.opendaylight.openflowplugin.api.openflow.device.Xid, Object)}
import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
import org.opendaylight.openflowplugin.impl.rpc.listener.ItemLifecycleListenerImpl;
-import org.opendaylight.openflowplugin.impl.services.RequestContextUtil;
+import org.opendaylight.openflowplugin.impl.services.util.RequestContextUtil;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
import org.opendaylight.openflowplugin.impl.statistics.services.dedicated.StatisticsGatheringOnTheFlyService;
import org.opendaylight.openflowplugin.impl.statistics.services.dedicated.StatisticsGatheringService;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class StatisticsContextImpl implements StatisticsContext {
+class StatisticsContextImpl<T extends OfHeader> implements StatisticsContext {
private static final Logger LOG = LoggerFactory.getLogger(StatisticsContextImpl.class);
private static final String CONNECTION_CLOSED = "Connection closed.";
private final DeviceState devState;
private final ListenableFuture<Boolean> emptyFuture;
private final boolean isStatisticsPollingOn;
- private final SinglePurposeMultipartReplyTranslator multipartReplyTranslator;
private final Object collectionStatTypeLock = new Object();
+ private final ConvertorExecutor convertorExecutor;
+ private final MultipartWriterProvider statisticsWriterProvider;
@GuardedBy("collectionStatTypeLock")
private List<MultipartType> collectingStatType;
- private StatisticsGatheringService statisticsGatheringService;
- private StatisticsGatheringOnTheFlyService statisticsGatheringOnTheFlyService;
+ private StatisticsGatheringService<T> statisticsGatheringService;
+ private StatisticsGatheringOnTheFlyService<T> statisticsGatheringOnTheFlyService;
private Timeout pollTimeout;
private final DeviceInfo deviceInfo;
private final StatisticsManager myManager;
final boolean isStatisticsPollingOn,
@Nonnull final LifecycleService lifecycleService,
@Nonnull final ConvertorExecutor convertorExecutor,
- @Nonnull final StatisticsManager myManager) {
+ @Nonnull final StatisticsManager myManager,
+ @Nonnull final MultipartWriterProvider statisticsWriterProvider) {
this.lifecycleService = lifecycleService;
this.deviceContext = lifecycleService.getDeviceContext();
this.devState = Preconditions.checkNotNull(deviceContext.getDeviceState());
this.isStatisticsPollingOn = isStatisticsPollingOn;
- multipartReplyTranslator = new SinglePurposeMultipartReplyTranslator(convertorExecutor);
+ this.convertorExecutor = convertorExecutor;
emptyFuture = Futures.immediateFuture(false);
- statisticsGatheringService = new StatisticsGatheringService(this, deviceContext);
- statisticsGatheringOnTheFlyService = new StatisticsGatheringOnTheFlyService(this, deviceContext, convertorExecutor);
+ statisticsGatheringService = new StatisticsGatheringService<>(this, deviceContext);
+ statisticsGatheringOnTheFlyService = new StatisticsGatheringOnTheFlyService<>(this,
+ deviceContext, convertorExecutor, statisticsWriterProvider);
itemLifeCycleListener = new ItemLifecycleListenerImpl(deviceContext);
statListForCollectingInitialization();
this.state = CONTEXT_STATE.INITIALIZATION;
this.deviceInfo = deviceInfo;
this.myManager = myManager;
this.lastDataGathering = null;
+ this.statisticsWriterProvider = statisticsWriterProvider;
}
@Override
private void statChainFuture(final Iterator<MultipartType> iterator, final SettableFuture<Boolean> resultFuture, final boolean initial) {
if (ConnectionContext.CONNECTION_STATE.RIP.equals(deviceContext.getPrimaryConnectionContext().getConnectionState())) {
final String errMsg = String.format("Device connection is closed for Node : %s.",
- getDeviceInfo().getNodeId());
+ getDeviceInfo().getNodeId());
LOG.debug(errMsg);
resultFuture.setException(new ConnectionException(errMsg));
return;
* Method checks a device state. It returns null for be able continue. Otherwise it returns immediateFuture
* which has to be returned from caller too
*
- * @return
+ * @return future
*/
@VisibleForTesting
ListenableFuture<Boolean> deviceConnectionCheck() {
switch (deviceContext.getPrimaryConnectionContext().getConnectionState()) {
case RIP:
final String errMsg = String.format("Device connection doesn't exist anymore. Primary connection status : %s",
- deviceContext.getPrimaryConnectionContext().getConnectionState());
+ deviceContext.getPrimaryConnectionContext().getConnectionState());
resultingFuture = Futures.immediateFailedFuture(new Throwable(errMsg));
break;
default:
//TODO: Refactor twice sending deviceContext into gatheringStatistics
private ListenableFuture<Boolean> collectFlowStatistics(final MultipartType multipartType, final boolean initial) {
return devState.isFlowStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
- statisticsGatheringOnTheFlyService,
- getDeviceInfo(),
- /*MultipartType.OFPMPFLOW*/ multipartType,
- deviceContext,
- deviceContext,
- initial, multipartReplyTranslator) : emptyFuture;
+ statisticsGatheringOnTheFlyService,
+ getDeviceInfo(),
+ /*MultipartType.OFPMPFLOW*/ multipartType,
+ deviceContext,
+ deviceContext,
+ initial,
+ convertorExecutor,
+ statisticsWriterProvider) : emptyFuture;
}
private ListenableFuture<Boolean> collectTableStatistics(final MultipartType multipartType) {
return devState.isTableStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
- statisticsGatheringService,
- getDeviceInfo(),
+ statisticsGatheringService,
+ getDeviceInfo(),
/*MultipartType.OFPMPTABLE*/ multipartType,
- deviceContext,
- deviceContext,
- false, multipartReplyTranslator) : emptyFuture;
+ deviceContext,
+ deviceContext,
+ false,
+ convertorExecutor,
+ statisticsWriterProvider) : emptyFuture;
}
private ListenableFuture<Boolean> collectPortStatistics(final MultipartType multipartType) {
return devState.isPortStatisticsAvailable() ? StatisticsGatheringUtils.gatherStatistics(
- statisticsGatheringService,
- getDeviceInfo(),
+ statisticsGatheringService,
+ getDeviceInfo(),
/*MultipartType.OFPMPPORTSTATS*/ multipartType,
- deviceContext,
- deviceContext,
- false, multipartReplyTranslator) : emptyFuture;
+ deviceContext,
+ deviceContext,
+ false,
+ convertorExecutor,
+ statisticsWriterProvider) : emptyFuture;
}
private ListenableFuture<Boolean> collectQueueStatistics(final MultipartType multipartType) {
return !devState.isQueueStatisticsAvailable() ? emptyFuture : StatisticsGatheringUtils.gatherStatistics(
- statisticsGatheringService,
- getDeviceInfo(),
+ statisticsGatheringService,
+ getDeviceInfo(),
/*MultipartType.OFPMPQUEUE*/ multipartType,
- deviceContext,
- deviceContext,
- false, multipartReplyTranslator);
+ deviceContext,
+ deviceContext,
+ false,
+ convertorExecutor,
+ statisticsWriterProvider);
}
private ListenableFuture<Boolean> collectGroupDescStatistics(final MultipartType multipartType) {
return devState.isGroupAvailable() ? StatisticsGatheringUtils.gatherStatistics(
- statisticsGatheringService,
- getDeviceInfo(),
+ statisticsGatheringService,
+ getDeviceInfo(),
/*MultipartType.OFPMPGROUPDESC*/ multipartType,
- deviceContext,
- deviceContext,
- false, multipartReplyTranslator) : emptyFuture;
+ deviceContext,
+ deviceContext,
+ false,
+ convertorExecutor,
+ statisticsWriterProvider) : emptyFuture;
}
private ListenableFuture<Boolean> collectGroupStatistics(final MultipartType multipartType) {
return devState.isGroupAvailable() ? StatisticsGatheringUtils.gatherStatistics(
- statisticsGatheringService,
- getDeviceInfo(),
+ statisticsGatheringService,
+ getDeviceInfo(),
/*MultipartType.OFPMPGROUP*/ multipartType,
- deviceContext,
- deviceContext,
- false, multipartReplyTranslator) : emptyFuture;
+ deviceContext,
+ deviceContext,
+ false,
+ convertorExecutor,
+ statisticsWriterProvider) : emptyFuture;
}
private ListenableFuture<Boolean> collectMeterConfigStatistics(final MultipartType multipartType) {
return devState.isMetersAvailable() ? StatisticsGatheringUtils.gatherStatistics(
- statisticsGatheringService,
- getDeviceInfo(),
+ statisticsGatheringService,
+ getDeviceInfo(),
/*MultipartType.OFPMPMETERCONFIG*/ multipartType,
- deviceContext,
- deviceContext,
- false, multipartReplyTranslator) : emptyFuture;
+ deviceContext,
+ deviceContext,
+ false,
+ convertorExecutor,
+ statisticsWriterProvider) : emptyFuture;
}
private ListenableFuture<Boolean> collectMeterStatistics(final MultipartType multipartType) {
return devState.isMetersAvailable() ? StatisticsGatheringUtils.gatherStatistics(
- statisticsGatheringService,
- getDeviceInfo(),
+ statisticsGatheringService,
+ getDeviceInfo(),
/*MultipartType.OFPMPMETER*/ multipartType,
- deviceContext,
- deviceContext,
- false, multipartReplyTranslator) : emptyFuture;
+ deviceContext,
+ deviceContext,
+ false,
+ convertorExecutor,
+ statisticsWriterProvider) : emptyFuture;
}
@VisibleForTesting
- void setStatisticsGatheringService(final StatisticsGatheringService statisticsGatheringService) {
+ void setStatisticsGatheringService(final StatisticsGatheringService<T> statisticsGatheringService) {
this.statisticsGatheringService = statisticsGatheringService;
}
@VisibleForTesting
- void setStatisticsGatheringOnTheFlyService(final StatisticsGatheringOnTheFlyService
- statisticsGatheringOnTheFlyService) {
+ void setStatisticsGatheringOnTheFlyService(final StatisticsGatheringOnTheFlyService<T> statisticsGatheringOnTheFlyService) {
this.statisticsGatheringOnTheFlyService = statisticsGatheringOnTheFlyService;
}
}
@Override
- public void onFailure(Throwable throwable) {
+ public void onFailure(@Nonnull Throwable throwable) {
LOG.warn("Initial gathering statistics unsuccessful for node {}", deviceInfo.getLOGValue());
lifecycleService.closeConnection();
}
public void setInitialSubmitHandler(final ClusterInitializationPhaseHandler initialSubmitHandler) {
this.initialSubmitHandler = initialSubmitHandler;
}
-}
\ No newline at end of file
+}
import com.google.common.base.Function;
import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureFallback;
import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.JdkFutureAdapters;
import com.google.common.util.concurrent.ListenableFuture;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainClosedException;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceRegistry;
import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
-import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
-import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
-import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.StatisticsGatherer;
-import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
+import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableStatisticsGatheringStatus;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableStatisticsGatheringStatusBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusEnd;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusEndBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.snapshot.gathering.status.grouping.SnapshotGatheringStatusStartBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.and.statistics.map.FlowTableAndStatisticsMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.flow.table.statistics.FlowTableStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterConfigStatsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.MeterStatisticsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.QueueStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
-import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Utils for gatherig statistics
+ * Utils for gathering statistics
*/
public final class StatisticsGatheringUtils {
- private static String DATE_AND_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
-
+ private static final String DATE_AND_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
private static final Logger LOG = LoggerFactory.getLogger(StatisticsGatheringUtils.class);
private static final String QUEUE2_REQCTX = "QUEUE2REQCTX-";
throw new IllegalStateException("This class should not be instantiated.");
}
- //TODO: Flow-,Group- and Meter- registry should be not in device context, consider move it in separate class
- static ListenableFuture<Boolean> gatherStatistics(final StatisticsGatherer statisticsGatheringService,
- final DeviceInfo deviceInfo,
- final MultipartType type,
- final TxFacade txFacade,
- final DeviceRegistry registry,
- final Boolean initial,
- final SinglePurposeMultipartReplyTranslator multipartReplyTranslator) {
- EventIdentifier wholeProcessEventIdentifier = null;
+ static <T extends OfHeader>ListenableFuture<Boolean> gatherStatistics(final StatisticsGatherer<T> statisticsGatheringService,
+ final DeviceInfo deviceInfo,
+ final MultipartType type,
+ final TxFacade txFacade,
+ final DeviceRegistry registry,
+ final Boolean initial,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+
+ final EventIdentifier eventIdentifier;
if (MultipartType.OFPMPFLOW.equals(type)) {
- wholeProcessEventIdentifier = new EventIdentifier(type.toString(), deviceInfo.getNodeId().getValue());
- EventsTimeCounter.markStart(wholeProcessEventIdentifier);
+ eventIdentifier = new EventIdentifier(type.toString(), deviceInfo.getNodeId().getValue());
+ EventsTimeCounter.markStart(eventIdentifier);
+ } else {
+ eventIdentifier = null;
}
- final EventIdentifier ofpQueuToRequestContextEventIdentifier = new EventIdentifier(QUEUE2_REQCTX + type.toString(), deviceInfo.getNodeId().toString());
- final ListenableFuture<RpcResult<List<MultipartReply>>> statisticsDataInFuture =
- JdkFutureAdapters.listenInPoolThread(statisticsGatheringService.getStatisticsOfType(
- ofpQueuToRequestContextEventIdentifier, type));
- return transformAndStoreStatisticsData(statisticsDataInFuture, deviceInfo, wholeProcessEventIdentifier, type, txFacade, registry, initial, multipartReplyTranslator);
- }
- private static ListenableFuture<Boolean> transformAndStoreStatisticsData(final ListenableFuture<RpcResult<List<MultipartReply>>> statisticsDataInFuture,
- final DeviceInfo deviceInfo,
- final EventIdentifier eventIdentifier,
- final MultipartType type,
- final TxFacade txFacade,
- final DeviceRegistry registry,
- final boolean initial,
- final SinglePurposeMultipartReplyTranslator multipartReplyTranslator) {
- return Futures.transform(statisticsDataInFuture, new AsyncFunction<RpcResult<List<MultipartReply>>, Boolean>() {
- @Nullable
- @Override
- public ListenableFuture<Boolean> apply(final RpcResult<List<MultipartReply>> rpcResult) {
- boolean isMultipartProcessed = Boolean.TRUE;
- if (rpcResult.isSuccessful()) {
- LOG.debug("Stats reply successfully received for node {} of type {}", deviceInfo.getNodeId(), type);
-
- // TODO: in case the result value is null then multipart data probably got processed on the fly -
- // TODO: this contract should by clearly stated and enforced - now simple true value is returned
- if (null != rpcResult.getResult()) {
- Iterable<? extends DataObject> allMultipartData = Collections.emptyList();
- DataObject multipartData = null;
-
-
- try {
- for (final MultipartReply singleReply : rpcResult.getResult()) {
- final List<? extends DataObject> multipartDataList = multipartReplyTranslator.translate(
- deviceInfo.getDatapathId(),
- deviceInfo.getVersion(), singleReply);
- multipartData = multipartDataList.get(0);
- allMultipartData = Iterables.concat(allMultipartData, multipartDataList);
+ return Futures.transform(
+ statisticsGatheringService.getStatisticsOfType(
+ new EventIdentifier(QUEUE2_REQCTX + type.toString(), deviceInfo.getNodeId().toString()),
+ type),
+ new AsyncFunction<RpcResult<List<T>>, Boolean>() {
+ @Nullable
+ @Override
+ public ListenableFuture<Boolean> apply(@Nonnull final RpcResult<List<T>> rpcResult) {
+ boolean isMultipartProcessed = Boolean.TRUE;
+
+ if (rpcResult.isSuccessful()) {
+ LOG.debug("Stats reply successfully received for node {} of type {}", deviceInfo.getNodeId(), type);
+
+ // TODO: in case the result value is null then multipart data probably got processed on the fly -
+ // TODO: this contract should by clearly stated and enforced - now simple true value is returned
+ if (Objects.nonNull(rpcResult.getResult()) && !rpcResult.getResult().isEmpty()) {
+ final List<DataContainer> allMultipartData;
+
+ try {
+ allMultipartData = rpcResult
+ .getResult()
+ .stream()
+ .map(reply -> MultipartReplyTranslatorUtil
+ .translate(reply, deviceInfo, convertorExecutor, null))
+ .filter(java.util.Optional::isPresent)
+ .map(java.util.Optional::get)
+ .collect(Collectors.toList());
+ } catch (final Exception e) {
+ LOG.warn("Stats processing of type {} for node {} failed during transformation step",
+ type, deviceInfo.getLOGValue(), e);
+ return Futures.immediateFailedFuture(e);
}
- } catch (final Exception e) {
- LOG.warn("stats processing of type {} for node {} failed during transfomation step",
- type, deviceInfo.getNodeId(), e);
- return Futures.immediateFailedFuture(e);
- }
-
- try {
- if (multipartData instanceof GroupStatisticsUpdated) {
- processGroupStatistics((Iterable<GroupStatisticsUpdated>) allMultipartData, deviceInfo, txFacade);
- } else if (multipartData instanceof MeterStatisticsUpdated) {
- processMetersStatistics((Iterable<MeterStatisticsUpdated>) allMultipartData, deviceInfo, txFacade);
- } else if (multipartData instanceof NodeConnectorStatisticsUpdate) {
- processNodeConnectorStatistics((Iterable<NodeConnectorStatisticsUpdate>) allMultipartData, deviceInfo, txFacade);
- } else if (multipartData instanceof FlowTableStatisticsUpdate) {
- processFlowTableStatistics((Iterable<FlowTableStatisticsUpdate>) allMultipartData, deviceInfo, txFacade);
- } else if (multipartData instanceof QueueStatisticsUpdate) {
- processQueueStatistics((Iterable<QueueStatisticsUpdate>) allMultipartData, deviceInfo, txFacade);
- } else if (multipartData instanceof FlowsStatisticsUpdate) {
- /* FlowStat Processing is realized by NettyThread only by initPhase, otherwise it is realized
- * by MD-SAL thread */
- return processFlowStatistics((Iterable<FlowsStatisticsUpdate>) allMultipartData, deviceInfo, txFacade, registry.getDeviceFlowRegistry(), initial, eventIdentifier);
-
- } else if (multipartData instanceof GroupDescStatsUpdated) {
- processGroupDescStats((Iterable<GroupDescStatsUpdated>) allMultipartData, deviceInfo, txFacade, registry.getDeviceGroupRegistry());
- } else if (multipartData instanceof MeterConfigStatsUpdated) {
- processMeterConfigStatsUpdated((Iterable<MeterConfigStatsUpdated>) allMultipartData, deviceInfo, txFacade, registry.getDeviceMeterRegistry());
- } else {
- isMultipartProcessed = Boolean.FALSE;
- }
- } catch (final Exception e) {
- LOG.warn("stats processing of type {} for node {} failed during write-to-tx step",
+ try {
+ return processStatistics(type, allMultipartData, txFacade, registry, deviceInfo,
+ statisticsWriterProvider,
+ eventIdentifier, initial);
+ } catch (final Exception e) {
+ LOG.warn("Stats processing of type {} for node {} failed during processing step",
type, deviceInfo.getNodeId(), e);
- return Futures.immediateFailedFuture(e);
+ return Futures.immediateFailedFuture(e);
+ }
+ } else {
+ LOG.debug("Stats reply was empty for node {} of type {}", deviceInfo.getNodeId(), type);
}
-
- LOG.debug("Stats reply added to transaction for node {} of type {}", deviceInfo.getNodeId(), type);
-
- //TODO : implement experimenter
} else {
- LOG.debug("Stats reply was empty for node {} of type {}", deviceInfo.getNodeId(), type);
+ LOG.warn("Stats reply FAILED for node {} of type {}: {}", deviceInfo.getNodeId(), type,
+ rpcResult.getErrors());
+ isMultipartProcessed = Boolean.FALSE;
}
- } else {
- LOG.debug("Stats reply FAILED for node {} of type {}: {}", deviceInfo.getNodeId(), type, rpcResult.getErrors());
- isMultipartProcessed = Boolean.FALSE;
+ return Futures.immediateFuture(isMultipartProcessed);
}
- return Futures.immediateFuture(isMultipartProcessed);
- }
- });
+ });
}
- private static void processMeterConfigStatsUpdated(final Iterable<MeterConfigStatsUpdated> data,
- final DeviceInfo deviceInfo,
- final TxFacade txFacade,
- final DeviceMeterRegistry meterRegistry) throws Exception {
- final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
- deleteAllKnownMeters(meterRegistry, fNodeIdent, txFacade);
- for (final MeterConfigStatsUpdated meterConfigStatsUpdated : data) {
- for (final MeterConfigStats meterConfigStats : meterConfigStatsUpdated.getMeterConfigStats()) {
- final MeterId meterId = meterConfigStats.getMeterId();
- final InstanceIdentifier<Meter> meterInstanceIdentifier = fNodeIdent.child(Meter.class, new MeterKey(meterId));
-
- final MeterBuilder meterBuilder = new MeterBuilder(meterConfigStats);
- meterBuilder.setKey(new MeterKey(meterId));
- meterBuilder.addAugmentation(NodeMeterStatistics.class, new NodeMeterStatisticsBuilder().build());
- meterRegistry.store(meterId);
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, meterInstanceIdentifier, meterBuilder.build());
- }
+ private static ListenableFuture<Boolean> processStatistics(final MultipartType type,
+ final List<? extends DataContainer> statistics,
+ final TxFacade txFacade,
+ final DeviceRegistry deviceRegistry,
+ final DeviceInfo deviceInfo,
+ final MultipartWriterProvider statisticsWriterProvider,
+ final EventIdentifier eventIdentifier,
+ final boolean initial) {
+
+ ListenableFuture<Void> future = Futures.immediateFuture(null);
+
+ final InstanceIdentifier<FlowCapableNode> instanceIdentifier = deviceInfo
+ .getNodeInstanceIdentifier()
+ .augmentation(FlowCapableNode.class);
+
+ switch (type) {
+ case OFPMPFLOW:
+ future = deleteAllKnownFlows(txFacade, instanceIdentifier, initial);
+ break;
+ case OFPMPMETERCONFIG:
+ deleteAllKnownMeters(txFacade, instanceIdentifier, deviceRegistry.getDeviceMeterRegistry());
+ break;
+ case OFPMPGROUPDESC:
+ deleteAllKnownGroups(txFacade, instanceIdentifier, deviceRegistry.getDeviceGroupRegistry());
+ break;
}
- txFacade.submitTransaction();
- }
- private static ListenableFuture<Boolean> processFlowStatistics(final Iterable<FlowsStatisticsUpdate> data,
- final DeviceInfo deviceInfo,
- final TxFacade txFacade,
- final DeviceFlowRegistry flowRegistry,
- final boolean initial,
- final EventIdentifier eventIdentifier) {
- final ListenableFuture<Void> deleteFuture = initial ? Futures.immediateFuture(null) : deleteAllKnownFlows(deviceInfo,
- flowRegistry, txFacade);
- return Futures.transform(deleteFuture, new Function<Void, Boolean>() {
-
- @Override
- public Boolean apply(final Void input) {
- writeFlowStatistics(data, deviceInfo, flowRegistry, txFacade);
+ return Futures.transform(future, (Function<Void, Boolean>) input -> {
+ if (writeStatistics(type, statistics, deviceInfo, statisticsWriterProvider)) {
txFacade.submitTransaction();
- EventsTimeCounter.markEnd(eventIdentifier);
+
+ if (MultipartType.OFPMPFLOW.equals(type)) {
+ EventsTimeCounter.markEnd(eventIdentifier);
+ }
+
+ LOG.debug("Stats reply added to transaction for node {} of type {}", deviceInfo.getNodeId(), type);
return Boolean.TRUE;
}
+
+ LOG.warn("Stats processing of type {} for node {} failed during write-to-tx step", type, deviceInfo.getLOGValue());
+ return Boolean.FALSE;
});
}
- public static void writeFlowStatistics(final Iterable<FlowsStatisticsUpdate> data,
- final DeviceInfo deviceInfo,
- final DeviceFlowRegistry registry,
- final TxFacade txFacade) {
- final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
+ private static boolean writeStatistics(final MultipartType type,
+ final List<? extends DataContainer> statistics,
+ final DeviceInfo deviceInfo,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ final AtomicBoolean result = new AtomicBoolean(false);
+
try {
- for (final FlowsStatisticsUpdate flowsStatistics : data) {
- for (final FlowAndStatisticsMapList flowStat : flowsStatistics.getFlowAndStatisticsMapList()) {
- final FlowBuilder flowBuilder = new FlowBuilder(flowStat);
- flowBuilder.addAugmentation(FlowStatisticsData.class, refineFlowStatisticsAugmentation(flowStat).build());
-
- final short tableId = flowStat.getTableId();
- final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(deviceInfo.getVersion(), flowBuilder.build());
- final FlowId flowId = registry.storeIfNecessary(flowRegistryKey);
-
- final FlowKey flowKey = new FlowKey(flowId);
- flowBuilder.setKey(flowKey);
- final TableKey tableKey = new TableKey(tableId);
- final InstanceIdentifier<Flow> flowIdent = fNodeIdent.child(Table.class, tableKey).child(Flow.class, flowKey);
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowIdent, flowBuilder.build());
+ statistics.forEach(stat -> statisticsWriterProvider.lookup(type).ifPresent(p -> {
+ final boolean write = p.write(stat, false);
+
+ if (!result.get()) {
+ result.set(write);
}
- }
- } catch (Exception e) {
- LOG.warn("Not able to write to transaction: {}", e.getMessage());
+ }));
+ } catch (final Exception ex) {
+ LOG.warn("Stats processing of type {} for node {} failed during write-to-tx step", type, deviceInfo.getLOGValue(), ex);
}
- }
- /**
- * Method extracts flow statistics out of flowAndStatistics model
- *
- * @param flowAndStats
- */
- private static FlowStatisticsDataBuilder refineFlowStatisticsAugmentation(final FlowAndStatisticsMapList flowAndStats) {
- final FlowStatisticsBuilder flowStatisticsBuilder = new FlowStatisticsBuilder(flowAndStats);
- final FlowStatisticsDataBuilder flowStatisticsDataBld = new FlowStatisticsDataBuilder();
- flowStatisticsDataBld.setFlowStatistics(flowStatisticsBuilder.build());
- return flowStatisticsDataBld;
+ return result.get();
}
- public static ListenableFuture<Void> deleteAllKnownFlows(final DeviceInfo deviceInfo,
- final DeviceFlowRegistry registry,
- final TxFacade txFacade) {
- final InstanceIdentifier<FlowCapableNode> flowCapableNodePath = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
- final ReadOnlyTransaction readTx = txFacade.getReadTransaction();
- final CheckedFuture<Optional<FlowCapableNode>, ReadFailedException> flowCapableNodeFuture = readTx.read(
- LogicalDatastoreType.OPERATIONAL, flowCapableNodePath);
-
- /* we wish to close readTx for fallBack */
- Futures.withFallback(flowCapableNodeFuture, new FutureFallback<Optional<FlowCapableNode>>() {
+ public static ListenableFuture<Void> deleteAllKnownFlows(final TxFacade txFacade,
+ final InstanceIdentifier<FlowCapableNode> instanceIdentifier,
+ final boolean initial) {
+ if (initial) {
+ return Futures.immediateFuture(null);
+ }
- @Override
- public ListenableFuture<Optional<FlowCapableNode>> create(final Throwable t) throws Exception {
+ final ReadOnlyTransaction readTx = txFacade.getReadTransaction();
+ return Futures.transform(Futures
+ .withFallback(readTx.read(LogicalDatastoreType.OPERATIONAL, instanceIdentifier), t -> {
+ // we wish to close readTx for fallBack
readTx.close();
return Futures.immediateFailedFuture(t);
- }
- });
- /*
- * we have to read actual tables with all information before we set empty Flow list, merge is expensive and
- * not applicable for lists
- */
- return Futures.transform(flowCapableNodeFuture, new AsyncFunction<Optional<FlowCapableNode>, Void>() {
-
- @Override
- public ListenableFuture<Void> apply(final Optional<FlowCapableNode> flowCapNodeOpt) throws Exception {
- if (flowCapNodeOpt.isPresent()) {
+ }), (Function<Optional<FlowCapableNode>, Void>)
+ flowCapNodeOpt -> {
+ // we have to read actual tables with all information before we set empty Flow list, merge is expensive and
+ // not applicable for lists
+ if (flowCapNodeOpt != null && flowCapNodeOpt.isPresent()) {
for (final Table tableData : flowCapNodeOpt.get().getTable()) {
- final Table table = new TableBuilder(tableData).setFlow(Collections.<Flow>emptyList()).build();
- final InstanceIdentifier<Table> iiToTable = flowCapableNodePath.child(Table.class, tableData.getKey());
+ final Table table = new TableBuilder(tableData).setFlow(Collections.emptyList()).build();
+ final InstanceIdentifier<Table> iiToTable = instanceIdentifier.child(Table.class, tableData.getKey());
txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, iiToTable, table);
}
}
- readTx.close();
- return Futures.immediateFuture(null);
- }
- });
- }
-
- private static void processQueueStatistics(final Iterable<QueueStatisticsUpdate> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
- // TODO: clean all queues of all node-connectors before writing up-to-date stats
- final InstanceIdentifier<Node> nodeIdent = deviceInfo.getNodeInstanceIdentifier();
- for (final QueueStatisticsUpdate queueStatisticsUpdate : data) {
- for (final QueueIdAndStatisticsMap queueStat : queueStatisticsUpdate.getQueueIdAndStatisticsMap()) {
- if (queueStat.getQueueId() != null) {
- final FlowCapableNodeConnectorQueueStatistics statChild =
- new FlowCapableNodeConnectorQueueStatisticsBuilder(queueStat).build();
- final FlowCapableNodeConnectorQueueStatisticsDataBuilder statBuild =
- new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
- statBuild.setFlowCapableNodeConnectorQueueStatistics(statChild);
- final QueueKey qKey = new QueueKey(queueStat.getQueueId());
- final InstanceIdentifier<Queue> queueIdent = nodeIdent
- .child(NodeConnector.class, new NodeConnectorKey(queueStat.getNodeConnectorId()))
- .augmentation(FlowCapableNodeConnector.class)
- .child(Queue.class, qKey);
- final QueueBuilder queueBuilder = new QueueBuilder()
- .setKey(qKey)
- .setQueueId(queueStat.getQueueId())
- // node-connector-id is already contained in parent node and the port-id here is of incompatible format
- .addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, statBuild.build());
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, queueIdent, queueBuilder.build());
- }
- }
- }
- txFacade.submitTransaction();
- }
-
- private static void processFlowTableStatistics(final Iterable<FlowTableStatisticsUpdate> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
- final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
- for (final FlowTableStatisticsUpdate flowTableStatisticsUpdate : data) {
-
- for (final FlowTableAndStatisticsMap tableStat : flowTableStatisticsUpdate.getFlowTableAndStatisticsMap()) {
- final InstanceIdentifier<FlowTableStatistics> tStatIdent = fNodeIdent.child(Table.class, new TableKey(tableStat.getTableId().getValue()))
- .augmentation(FlowTableStatisticsData.class).child(FlowTableStatistics.class);
- final FlowTableStatistics stats = new FlowTableStatisticsBuilder(tableStat).build();
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tStatIdent, stats);
- }
- }
- txFacade.submitTransaction();
- }
-
- private static void processNodeConnectorStatistics(final Iterable<NodeConnectorStatisticsUpdate> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
- final InstanceIdentifier<Node> nodeIdent = deviceInfo.getNodeInstanceIdentifier();
- for (final NodeConnectorStatisticsUpdate nodeConnectorStatisticsUpdate : data) {
- for (final NodeConnectorStatisticsAndPortNumberMap nConnectPort : nodeConnectorStatisticsUpdate.getNodeConnectorStatisticsAndPortNumberMap()) {
- final FlowCapableNodeConnectorStatistics stats = new FlowCapableNodeConnectorStatisticsBuilder(nConnectPort).build();
- final NodeConnectorKey key = new NodeConnectorKey(nConnectPort.getNodeConnectorId());
- final InstanceIdentifier<NodeConnector> nodeConnectorIdent = nodeIdent.child(NodeConnector.class, key);
- final InstanceIdentifier<FlowCapableNodeConnectorStatisticsData> nodeConnStatIdent = nodeConnectorIdent
- .augmentation(FlowCapableNodeConnectorStatisticsData.class);
- final InstanceIdentifier<FlowCapableNodeConnectorStatistics> flowCapNodeConnStatIdent =
- nodeConnStatIdent.child(FlowCapableNodeConnectorStatistics.class);
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, flowCapNodeConnStatIdent, stats);
- }
- }
- txFacade.submitTransaction();
+ readTx.close();
+ return null;
+ });
}
- private static void processMetersStatistics(final Iterable<MeterStatisticsUpdated> data,
- final DeviceInfo deviceInfo,
- final TxFacade txFacade) throws Exception {
- final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
- for (final MeterStatisticsUpdated meterStatisticsUpdated : data) {
- for (final MeterStats mStat : meterStatisticsUpdated.getMeterStats()) {
- final MeterStatistics stats = new MeterStatisticsBuilder(mStat).build();
- final MeterId meterId = mStat.getMeterId();
- final InstanceIdentifier<Meter> meterIdent = fNodeIdent.child(Meter.class, new MeterKey(meterId));
- final InstanceIdentifier<NodeMeterStatistics> nodeMeterStatIdent = meterIdent
- .augmentation(NodeMeterStatistics.class);
- final InstanceIdentifier<MeterStatistics> msIdent = nodeMeterStatIdent.child(MeterStatistics.class);
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, msIdent, stats);
- }
- }
- txFacade.submitTransaction();
- }
+ private static void deleteAllKnownMeters(final TxFacade txFacade,
+ final InstanceIdentifier<FlowCapableNode> instanceIdentifier,
+ final DeviceMeterRegistry meterRegistry) {
+ meterRegistry.getAllMeterIds().forEach(meterId -> txFacade
+ .addDeleteToTxChain(
+ LogicalDatastoreType.OPERATIONAL,
+ instanceIdentifier.child(Meter.class, new MeterKey(meterId))));
- private static void deleteAllKnownMeters(final DeviceMeterRegistry meterRegistry, final InstanceIdentifier<FlowCapableNode> fNodeIdent, final TxFacade txFacade) throws Exception {
- for (final MeterId meterId : meterRegistry.getAllMeterIds()) {
- final InstanceIdentifier<Meter> meterIdent = fNodeIdent.child(Meter.class, new MeterKey(meterId));
- txFacade.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, meterIdent);
- }
meterRegistry.removeMarked();
}
- private static void processGroupDescStats(final Iterable<GroupDescStatsUpdated> data, final DeviceInfo deviceInfo, final TxFacade txFacade, final DeviceGroupRegistry groupRegistry) throws Exception {
- final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
- deleteAllKnownGroups(txFacade, fNodeIdent, groupRegistry);
-
- for (final GroupDescStatsUpdated groupDescStatsUpdated : data) {
- for (final GroupDescStats groupDescStats : groupDescStatsUpdated.getGroupDescStats()) {
- final GroupId groupId = groupDescStats.getGroupId();
-
- final GroupBuilder groupBuilder = new GroupBuilder(groupDescStats);
- groupBuilder.setKey(new GroupKey(groupId));
- groupBuilder.addAugmentation(NodeGroupStatistics.class, new NodeGroupStatisticsBuilder().build());
+ private static void deleteAllKnownGroups(final TxFacade txFacade,
+ final InstanceIdentifier<FlowCapableNode> instanceIdentifier,
+ final DeviceGroupRegistry groupRegistry) {
+ groupRegistry.getAllGroupIds().forEach(groupId -> txFacade
+ .addDeleteToTxChain(
+ LogicalDatastoreType.OPERATIONAL,
+ instanceIdentifier.child(Group.class, new GroupKey(groupId))));
- final InstanceIdentifier<Group> groupIdent = fNodeIdent.child(Group.class, new GroupKey(groupId));
-
- groupRegistry.store(groupId);
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, groupIdent, groupBuilder.build());
- }
- }
- txFacade.submitTransaction();
- }
-
- private static void deleteAllKnownGroups(final TxFacade txFacade, final InstanceIdentifier<FlowCapableNode> fNodeIdent, final DeviceGroupRegistry groupRegistry) throws Exception {
- for (final GroupId groupId : groupRegistry.getAllGroupIds()) {
- final InstanceIdentifier<Group> groupIdent = fNodeIdent.child(Group.class, new GroupKey(groupId));
- txFacade.addDeleteToTxChain(LogicalDatastoreType.OPERATIONAL, groupIdent);
- }
groupRegistry.removeMarked();
}
- private static void processGroupStatistics(final Iterable<GroupStatisticsUpdated> data, final DeviceInfo deviceInfo, final TxFacade txFacade) throws Exception {
- final InstanceIdentifier<FlowCapableNode> fNodeIdent = assembleFlowCapableNodeInstanceIdentifier(deviceInfo);
- for (final GroupStatisticsUpdated groupStatistics : data) {
- for (final GroupStats groupStats : groupStatistics.getGroupStats()) {
-
- final InstanceIdentifier<Group> groupIdent = fNodeIdent.child(Group.class, new GroupKey(groupStats.getGroupId()));
- final InstanceIdentifier<NodeGroupStatistics> nGroupStatIdent = groupIdent
- .augmentation(NodeGroupStatistics.class);
-
- final InstanceIdentifier<GroupStatistics> gsIdent = nGroupStatIdent.child(GroupStatistics.class);
- final GroupStatistics stats = new GroupStatisticsBuilder(groupStats).build();
- txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL, gsIdent, stats);
- }
- }
- txFacade.submitTransaction();
- }
-
- private static InstanceIdentifier<FlowCapableNode> assembleFlowCapableNodeInstanceIdentifier(final DeviceInfo deviceInfo) {
- return deviceInfo.getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
- }
-
/**
* Writes snapshot gathering start timestamp + cleans end mark
*
*/
static void markDeviceStateSnapshotStart(final DeviceContext deviceContext) {
final InstanceIdentifier<FlowCapableStatisticsGatheringStatus> statusPath = deviceContext.getDeviceInfo()
- .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class);
+ .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class);
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_AND_TIME_FORMAT);
final FlowCapableStatisticsGatheringStatus gatheringStatus = new FlowCapableStatisticsGatheringStatusBuilder()
- .setSnapshotGatheringStatusStart(new SnapshotGatheringStatusStartBuilder()
- .setBegin(new DateAndTime(simpleDateFormat.format(new Date())))
- .build())
- .setSnapshotGatheringStatusEnd(null) // TODO: reconsider if really need to clean end mark here
- .build();
+ .setSnapshotGatheringStatusStart(new SnapshotGatheringStatusStartBuilder()
+ .setBegin(new DateAndTime(simpleDateFormat.format(new Date())))
+ .build())
+ .setSnapshotGatheringStatusEnd(null) // TODO: reconsider if really need to clean end mark here
+ .build();
try {
deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, statusPath, gatheringStatus);
} catch (final TransactionChainClosedException e) {
*/
static void markDeviceStateSnapshotEnd(final DeviceContext deviceContext, final boolean succeeded) {
final InstanceIdentifier<SnapshotGatheringStatusEnd> statusEndPath = deviceContext.getDeviceInfo()
- .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class)
- .child(SnapshotGatheringStatusEnd.class);
+ .getNodeInstanceIdentifier().augmentation(FlowCapableStatisticsGatheringStatus.class)
+ .child(SnapshotGatheringStatusEnd.class);
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_AND_TIME_FORMAT);
final SnapshotGatheringStatusEnd gatheringStatus = new SnapshotGatheringStatusEndBuilder()
- .setEnd(new DateAndTime(simpleDateFormat.format(new Date())))
- .setSucceeded(succeeded)
- .build();
+ .setEnd(new DateAndTime(simpleDateFormat.format(new Date())))
+ .setSucceeded(succeeded)
+ .build();
try {
deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, statusEndPath, gatheringStatus);
} catch (TransactionChainClosedException e) {
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.util.HashedWheelTimer;
+import io.netty.util.Timeout;
+import io.netty.util.TimerTask;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
import org.opendaylight.openflowplugin.api.openflow.rpc.ItemLifeCycleSource;
import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsContext;
import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.ChangeStatisticsWorkModeInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.GetStatisticsWorkModeOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.sm.control.rev150812.GetStatisticsWorkModeOutputBuilder;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timeout;
-import io.netty.util.TimerTask;
public class StatisticsManagerImpl implements StatisticsManager, StatisticsManagerControlService {
private static final long DEFAULT_STATS_TIMEOUT_SEC = 50L;
private final ConvertorExecutor converterExecutor;
-
private DeviceInitializationPhaseHandler deviceInitPhaseHandler;
private DeviceTerminationPhaseHandler deviceTerminationPhaseHandler;
public void onDeviceContextLevelUp(final DeviceInfo deviceInfo,
final LifecycleService lifecycleService) throws Exception {
+ final MultipartWriterProvider statisticsWriterProvider = MultipartWriterProviderFactory
+ .createDefaultProvider(lifecycleService.getDeviceContext());
+
final StatisticsContext statisticsContext =
- new StatisticsContextImpl(
- deviceInfo,
- isStatisticsPollingOn,
- lifecycleService,
- converterExecutor,
- this);
+ lifecycleService.getDeviceContext().canUseSingleLayerSerialization() ?
+ new StatisticsContextImpl<MultipartReply>(
+ deviceInfo,
+ isStatisticsPollingOn,
+ lifecycleService,
+ converterExecutor,
+ this,
+ statisticsWriterProvider) :
+ new StatisticsContextImpl<org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
+ .MultipartReply>(
+ deviceInfo,
+ isStatisticsPollingOn,
+ lifecycleService,
+ converterExecutor,
+ this,
+ statisticsWriterProvider);
Verify.verify(
contexts.putIfAbsent(deviceInfo, statisticsContext) == null,
import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.FlowStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.FlowStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.GroupStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
return message.build();
}
-}
\ No newline at end of file
+}
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.MeterStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.NodeConnectorStatisticsToNotificationTransformer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.QueueStatisticsToNotificationTransformer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.QueueStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.FlowStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.util.GroupUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.GroupStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.MeterStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.QueueStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
*/
package org.opendaylight.openflowplugin.impl.statistics.services;
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.Futures;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
-import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
import org.opendaylight.openflowplugin.api.openflow.statistics.compatibility.Delegator;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerAggregateFlowMultipartService;
+import org.opendaylight.openflowplugin.impl.services.singlelayer.SingleLayerAggregateFlowMultipartService;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowStatisticsFromFlowTableOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.get.aggregate.flow.statistics.from.flow.table._for.given.match.output.AggregatedFlowStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
/**
* @author joe
*/
public class OpendaylightFlowStatisticsServiceImpl implements OpendaylightFlowStatisticsService, Delegator<OpendaylightFlowStatisticsService> {
- private final Function<RpcResult<List<MultipartReply>>, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> matchingConvertor =
- new Function<RpcResult<List<MultipartReply>>, RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>>() {
- @Override
- public RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput> apply(final RpcResult<List<MultipartReply>> input) {
- final DeviceInfo deviceInfo = matchingFlowsInTable.getDeviceInfo();
- final RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput> rpcResult;
- if (input.isSuccessful()) {
- MultipartReply reply = input.getResult().get(0);
- final TranslatorKey translatorKey = new TranslatorKey(reply.getVersion(), MultipartReplyAggregateCase.class.getName());
- final MessageTranslator<MultipartReply, AggregatedFlowStatistics> messageTranslator = translatorLibrary.lookupTranslator(translatorKey);
- List<AggregatedFlowStatistics> aggregStats = new ArrayList<AggregatedFlowStatistics>();
-
- for (MultipartReply multipartReply : input.getResult()) {
- aggregStats.add(messageTranslator.translate(multipartReply, deviceInfo, null));
- }
-
- GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder =
- new GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder();
- getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder.setAggregatedFlowStatistics(aggregStats);
-
- rpcResult = RpcResultBuilder
- .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>success()
- .withResult(getAggregateFlowStatisticsFromFlowTableForGivenMatchOutputBuilder.build())
- .build();
-
- } else {
- rpcResult = RpcResultBuilder
- .<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>failed()
- .withRpcErrors(input.getErrors())
- .build();
- }
- return rpcResult;
- }
- };
-
- private final MatchingFlowsInTableService matchingFlowsInTable;
- private final TranslatorLibrary translatorLibrary;
+ private final SingleLayerAggregateFlowMultipartService singleLayerService;
+ private final MultiLayerAggregateFlowMultipartService multiLayerService;
private OpendaylightFlowStatisticsService delegate;
public static OpendaylightFlowStatisticsServiceImpl createWithOook(final RequestContextStack requestContextStack,
return new OpendaylightFlowStatisticsServiceImpl(requestContextStack, deviceContext, deviceContext.oook(), convertorExecutor);
}
- public OpendaylightFlowStatisticsServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext,
- final TranslatorLibrary translatorLibrary, final ConvertorExecutor convertorExecutor) {
- matchingFlowsInTable = new MatchingFlowsInTableService(requestContextStack, deviceContext, convertorExecutor);
- this.translatorLibrary = translatorLibrary;
+ public OpendaylightFlowStatisticsServiceImpl(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final TranslatorLibrary translatorLibrary,
+ final ConvertorExecutor convertorExecutor) {
+ singleLayerService = new SingleLayerAggregateFlowMultipartService(requestContextStack, deviceContext,
+ convertorExecutor);
+ multiLayerService = new MultiLayerAggregateFlowMultipartService(requestContextStack, deviceContext,
+ convertorExecutor, translatorLibrary);
}
@Override
@Override
public Future<RpcResult<GetAggregateFlowStatisticsFromFlowTableForGivenMatchOutput>> getAggregateFlowStatisticsFromFlowTableForGivenMatch(
final GetAggregateFlowStatisticsFromFlowTableForGivenMatchInput input) {
- return Futures.transform(matchingFlowsInTable.handleServiceCall(input), matchingConvertor);
+ return singleLayerService.canUseSingleLayerSerialization()
+ ? singleLayerService.handleAndReply(input)
+ : multiLayerService.handleAndReply(input);
}
/**
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.AbstractCompatibleStatService;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.NodeConnectorStatisticsToNotificationTransformer;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.Notification;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
/**
* pulled up common functionality of notification emitting stats services (backward compatibility relic)
*/
-public abstract class AbstractCompatibleStatService<I, O, N extends Notification> extends AbstractMultipartService<I> implements BackwardCompatibleAtomicService<I, O> {
+public abstract class AbstractCompatibleStatService<I extends DataContainer, O, N extends Notification> extends AbstractMultipartService<I, MultipartReply> implements BackwardCompatibleAtomicService<I, O> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractCompatibleStatService.class);
package org.opendaylight.openflowplugin.impl.statistics.services.dedicated;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
-import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.StatisticsGatherer;
import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory;
import org.opendaylight.openflowplugin.impl.services.AbstractMultipartOnTheFlyService;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
/**
* collects statistics and processes them on the fly
*/
-public class StatisticsGatheringOnTheFlyService extends AbstractMultipartOnTheFlyService<MultipartType> implements StatisticsGatherer {
+public class StatisticsGatheringOnTheFlyService<T extends OfHeader>
+ extends AbstractMultipartOnTheFlyService<MultipartType, T>
+ implements StatisticsGatherer<T> {
private static final Logger LOG = LoggerFactory.getLogger(StatisticsGatheringOnTheFlyService.class);
- public StatisticsGatheringOnTheFlyService(final RequestContextStack requestContextStack, final DeviceContext deviceContext, final ConvertorExecutor convertorExecutor) {
- super(requestContextStack, deviceContext, convertorExecutor);
+ public StatisticsGatheringOnTheFlyService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
}
@Override
- public Future<RpcResult<List<MultipartReply>>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) {
+ public ListenableFuture<RpcResult<List<T>>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) {
LOG.debug("Getting statistics (onTheFly) for node {} of type {}", getDeviceInfo().getNodeId(), type);
EventsTimeCounter.markStart(eventIdentifier);
setEventIdentifier(eventIdentifier);
protected OfHeader buildRequest(final Xid xid, final MultipartType input) throws ServiceException {
return MultipartRequestInputFactory.makeMultipartRequestInput(xid.getValue(), getVersion(), input);
}
+
}
package org.opendaylight.openflowplugin.impl.statistics.services.dedicated;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
-import java.util.concurrent.Future;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.StatisticsGatherer;
import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory;
import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/**
- * Created by Martin Bobak <mbobak@cisco.com> on 4.4.2015.
- */
-public class StatisticsGatheringService extends AbstractMultipartService<MultipartType> implements StatisticsGatherer {
+public class StatisticsGatheringService<T extends OfHeader>
+ extends AbstractMultipartService<MultipartType, T>
+ implements StatisticsGatherer<T> {
private static final Logger LOG = LoggerFactory.getLogger(StatisticsGatheringService.class);
}
@Override
- public Future<RpcResult<List<MultipartReply>>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) {
+ public ListenableFuture<RpcResult<List<T>>> getStatisticsOfType(final EventIdentifier eventIdentifier, final MultipartType type) {
LOG.debug("Getting statistics for node {} of type {}", getDeviceInfo().getNodeId(), type);
EventsTimeCounter.markStart(eventIdentifier);
setEventIdentifier(eventIdentifier);
protected OfHeader buildRequest(final Xid xid, final MultipartType input) throws ServiceException {
return MultipartRequestInputFactory.makeMultipartRequestInput(xid.getValue(), getVersion(), input);
}
+
}
package org.opendaylight.openflowplugin.impl.statistics.services.direct;
-import com.google.common.base.Function;
import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
import java.util.concurrent.Future;
+import java.util.function.Function;
import javax.annotation.Nullable;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService;
-import org.opendaylight.openflowplugin.impl.services.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.RequestInputUtils;
+import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.impl.services.ServiceException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.StoreStatsGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
* @param <I> the input type parameter
* @param <O> the output type parameter
*/
-public abstract class AbstractDirectStatisticsService<I extends StoreStatsGrouping, O> extends AbstractMultipartService<I> {
+abstract class AbstractDirectStatisticsService<I extends StoreStatsGrouping, O extends DataContainer, T extends OfHeader>
+ extends AbstractMultipartService<I, T> {
- private final Function<RpcResult<List<MultipartReply>>, RpcResult<O>> resultTransformFunction =
- new Function<RpcResult<List<MultipartReply>>, RpcResult<O>>() {
+ private final Function<RpcResult<List<T>>, RpcResult<O>> resultTransformFunction =
+ new Function<RpcResult<List<T>>, RpcResult<O>>() {
@Nullable
@Override
- public RpcResult<O> apply(@Nullable RpcResult<List<MultipartReply>> input) {
- Preconditions.checkNotNull(input);
- final O reply = buildReply(input.getResult(), input.isSuccessful());
- return RpcResultBuilder.success(reply).build();
+ public RpcResult<O> apply(@Nullable RpcResult<List<T>> input) {
+ return Preconditions.checkNotNull(input).isSuccessful()
+ ? RpcResultBuilder.success(buildReply(input.getResult(), input.isSuccessful())).build()
+ : RpcResultBuilder.<O>failed().build();
}
};
- private final AsyncFunction<RpcResult<O>, RpcResult<O>> resultStoreFunction =
- new AsyncFunction<RpcResult<O>, RpcResult<O>>() {
+ private final Function<RpcResult<O>, RpcResult<O>> resultStoreFunction =
+ new Function<RpcResult<O>, RpcResult<O>>() {
@Nullable
@Override
- public ListenableFuture<RpcResult<O>> apply(@Nullable RpcResult<O> input) throws Exception {
+ public RpcResult<O> apply(@Nullable RpcResult<O> input) {
Preconditions.checkNotNull(input);
if (input.isSuccessful()) {
- storeStatistics(input.getResult());
- getTxFacade().submitTransaction(); // TODO: If submitTransaction will ever return future, chain it
+ multipartWriterProvider
+ .lookup(multipartType)
+ .ifPresent(writer -> {
+ writer.write(input.getResult(), true);
+ getTxFacade().submitTransaction();
+ });
}
- return Futures.immediateFuture(input);
+ return input;
}
};
private final MultipartType multipartType;
- private final ConvertorExecutor convertorExecutor;
private final OpenflowVersion ofVersion = OpenflowVersion.get(getVersion());
+ private final ConvertorExecutor convertorExecutor;
+ private final MultipartWriterProvider multipartWriterProvider;
+
/**
* Instantiates a new Abstract direct statistics service.
- *
- * @param multipartType the multipart type
- * @param requestContextStack the request context stack
- * @param deviceContext the device context
- * @param convertorExecutor
+ * @param multipartType the multipart type
+ * @param requestContextStack the request context stack
+ * @param deviceContext the device context
+ * @param convertorExecutor convertor executor
+ * @param multipartWriterProvider statistics writer provider
*/
- protected AbstractDirectStatisticsService(MultipartType multipartType, RequestContextStack requestContextStack,
- DeviceContext deviceContext, ConvertorExecutor convertorExecutor) {
+ AbstractDirectStatisticsService(final MultipartType multipartType,
+ final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider multipartWriterProvider) {
super(requestContextStack, deviceContext);
this.multipartType = multipartType;
this.convertorExecutor = convertorExecutor;
- }
-
- protected ConvertorExecutor getConvertorExecutor() {
- return convertorExecutor;
+ this.multipartWriterProvider = multipartWriterProvider;
}
/**
* @param input the input
* @return the future
*/
- public Future<RpcResult<O>> handleAndReply(final I input) {
- final ListenableFuture<RpcResult<List<MultipartReply>>> rpcReply = handleServiceCall(input);
- ListenableFuture<RpcResult<O>> rpcResult = Futures.transform(rpcReply, resultTransformFunction);
+ Future<RpcResult<O>> handleAndReply(final I input) {
+ final ListenableFuture<RpcResult<List<T>>> rpcReply = handleServiceCall(input);
+ ListenableFuture<RpcResult<O>> rpcResult = Futures.transform(rpcReply, resultTransformFunction::apply);
if (Boolean.TRUE.equals(input.isStoreStats())) {
- rpcResult = Futures.transform(rpcResult, resultStoreFunction);
+ rpcResult = Futures.transform(rpcResult, resultStoreFunction::apply);
}
return rpcResult;
.build();
}
+ /**
+ * Get convertor executor
+ * @return convertor executor
+ */
+ protected ConvertorExecutor getConvertorExecutor() {
+ return convertorExecutor;
+ }
+
/**
* Gets openflow version.
*
* @param input the input
* @return the multipart request body
*/
- protected abstract MultipartRequestBody buildRequestBody(I input);
+ public abstract MultipartRequestBody buildRequestBody(I input);
/**
* Build output from multipart reply input.
* @param input the input
* @return the output
*/
- protected abstract O buildReply(List<MultipartReply> input, boolean success);
+ protected abstract O buildReply(List<T> input, boolean success);
- /**
- * Store statistics.
- * TODO: Remove dependency on deviceContext from derived methods
- * TODO: Return future, so we will be able to chain it
- *
- * @param output the output
- * @throws Exception the exception
- */
- protected abstract void storeStatistics(O output) throws Exception;
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
+import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
+
+/**
+ * The Flow direct statistics service.
+ */
+public abstract class AbstractFlowDirectStatisticsService<T extends OfHeader>
+ extends AbstractDirectStatisticsService<GetFlowStatisticsInput, GetFlowStatisticsOutput, T> {
+
+ protected AbstractFlowDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(MultipartType.OFPMPFLOW, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ public MultipartRequestBody buildRequestBody(GetFlowStatisticsInput input) {
+ final MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
+
+ if (input.getTableId() != null) {
+ mprFlowRequestBuilder.setTableId(input.getTableId());
+ } else {
+ mprFlowRequestBuilder.setTableId(OFConstants.OFPTT_ALL);
+ }
+
+ if (input.getOutPort() != null) {
+ mprFlowRequestBuilder.setOutPort(input.getOutPort().longValue());
+ } else {
+ mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
+ }
+
+ if (input.getOutGroup() != null) {
+ mprFlowRequestBuilder.setOutGroup(input.getOutGroup());
+ } else {
+ mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
+ }
+
+ if (input.getCookie() != null) {
+ mprFlowRequestBuilder.setCookie(input.getCookie().getValue());
+ } else {
+ mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
+ }
+
+ if (input.getCookieMask() != null) {
+ mprFlowRequestBuilder.setCookieMask(input.getCookieMask().getValue());
+ } else {
+ mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
+ }
+
+ MatchReactor.getInstance().convert(input.getMatch(), getVersion(), mprFlowRequestBuilder, getConvertorExecutor());
+
+ return new MultipartRequestFlowCaseBuilder()
+ .setMultipartRequestFlow(mprFlowRequestBuilder.build())
+ .build();
+ }
+
+ /**
+ * Get flow ID from #{@link org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry} or
+ * create alien ID
+ * @param flowStatistics flow statistics
+ * @return generated flow ID
+ */
+ protected FlowId generateFlowId(FlowAndStatisticsMapList flowStatistics) {
+ final FlowStatisticsDataBuilder flowStatisticsDataBld = new FlowStatisticsDataBuilder()
+ .setFlowStatistics(new FlowStatisticsBuilder(flowStatistics).build());
+
+ final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics)
+ .addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build());
+
+ final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(getVersion(), flowBuilder.build());
+ return getDeviceRegistry().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
+
+/**
+ * The Group direct statistics service.
+ */
+public abstract class AbstractGroupDirectStatisticsService<T extends OfHeader>
+ extends AbstractDirectStatisticsService<GetGroupStatisticsInput, GetGroupStatisticsOutput, T> {
+
+ protected AbstractGroupDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(MultipartType.OFPMPGROUP, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ public MultipartRequestBody buildRequestBody(GetGroupStatisticsInput input) {
+ final MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
+
+ if (input.getGroupId() != null) {
+ mprGroupBuild.setGroupId(new GroupId(input.getGroupId().getValue()));
+ } else {
+ mprGroupBuild.setGroupId(new GroupId(OFConstants.OFPG_ALL));
+ }
+
+ return new MultipartRequestGroupCaseBuilder()
+ .setMultipartRequestGroup(mprGroupBuild.build())
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
+
+/**
+ * The Meter direct statistics service.
+ */
+public abstract class AbstractMeterDirectStatisticsService<T extends OfHeader> extends
+ AbstractDirectStatisticsService<GetMeterStatisticsInput, GetMeterStatisticsOutput, T> {
+
+ public AbstractMeterDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(MultipartType.OFPMPMETER, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ public MultipartRequestBody buildRequestBody(GetMeterStatisticsInput input) {
+ final MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
+
+ if (input.getMeterId() != null) {
+ mprMeterBuild.setMeterId(new MeterId(input.getMeterId().getValue()));
+ } else {
+ mprMeterBuild.setMeterId(new MeterId(OFConstants.OFPM_ALL));
+ }
+
+ return new MultipartRequestMeterCaseBuilder()
+ .setMultipartRequestMeter(mprMeterBuild.build())
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder;
+
+/**
+ * The Node connector direct statistics service.
+ */
+public abstract class AbstractPortDirectStatisticsService<T extends OfHeader>
+ extends AbstractDirectStatisticsService<GetNodeConnectorStatisticsInput, GetNodeConnectorStatisticsOutput, T> {
+
+ public AbstractPortDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(MultipartType.OFPMPPORTSTATS, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ public MultipartRequestBody buildRequestBody(GetNodeConnectorStatisticsInput input) {
+ final MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder();
+
+ if (input.getNodeConnectorId() != null) {
+ mprPortStatsBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(getOfVersion(), input.getNodeConnectorId()));
+ } else {
+ mprPortStatsBuilder.setPortNo(OFConstants.OFPP_ANY);
+ }
+
+ return new MultipartRequestPortStatsCaseBuilder()
+ .setMultipartRequestPortStats(mprPortStatsBuilder.build())
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder;
+
+/**
+ * The Queue direct statistics service.
+ */
+public abstract class AbstractQueueDirectStatisticsService<T extends OfHeader>
+ extends AbstractDirectStatisticsService<GetQueueStatisticsInput, GetQueueStatisticsOutput, T> {
+
+ public AbstractQueueDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(MultipartType.OFPMPQUEUE, requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ public MultipartRequestBody buildRequestBody(GetQueueStatisticsInput input) {
+ final MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
+
+ if (input.getQueueId() != null) {
+ mprQueueBuilder.setQueueId(input.getQueueId().getValue());
+ } else {
+ mprQueueBuilder.setQueueId(OFConstants.OFPQ_ALL);
+ }
+
+ if (input.getNodeConnectorId() != null) {
+ mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(getOfVersion(), input.getNodeConnectorId()));
+ } else {
+ mprQueueBuilder.setPortNo(OFConstants.OFPP_ANY);
+ }
+
+ return new MultipartRequestQueueCaseBuilder()
+ .setMultipartRequestQueue(mprQueueBuilder.build())
+ .build();
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
-import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
-import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchReactor;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * The Flow direct statistics service.
- */
-public class FlowDirectStatisticsService extends AbstractDirectStatisticsService<GetFlowStatisticsInput, GetFlowStatisticsOutput> {
- private final FlowStatsResponseConvertorData data;
-
- /**
- * Instantiates a new Flow direct statistics service.
- * @param requestContextStack the request context stack
- * @param deviceContext the device context
- * @param convertorExecutor
- */
- public FlowDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) {
- super(MultipartType.OFPMPFLOW, requestContextStack, deviceContext, convertorExecutor);
- data = new FlowStatsResponseConvertorData(getVersion());
- data.setDatapathId(getDatapathId());
- data.setMatchPath(MatchPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_MATCH);
- }
-
- @Override
- protected MultipartRequestBody buildRequestBody(GetFlowStatisticsInput input) {
- final MultipartRequestFlowBuilder mprFlowRequestBuilder = new MultipartRequestFlowBuilder();
-
- if (input.getTableId() != null) {
- mprFlowRequestBuilder.setTableId(input.getTableId());
- } else {
- mprFlowRequestBuilder.setTableId(OFConstants.OFPTT_ALL);
- }
-
- if (input.getOutPort() != null) {
- mprFlowRequestBuilder.setOutPort(input.getOutPort().longValue());
- } else {
- mprFlowRequestBuilder.setOutPort(OFConstants.OFPP_ANY);
- }
-
- if (input.getOutGroup() != null) {
- mprFlowRequestBuilder.setOutGroup(input.getOutGroup());
- } else {
- mprFlowRequestBuilder.setOutGroup(OFConstants.OFPG_ANY);
- }
-
- if (input.getCookie() != null) {
- mprFlowRequestBuilder.setCookie(input.getCookie().getValue());
- } else {
- mprFlowRequestBuilder.setCookie(OFConstants.DEFAULT_COOKIE);
- }
-
- if (input.getCookieMask() != null) {
- mprFlowRequestBuilder.setCookieMask(input.getCookieMask().getValue());
- } else {
- mprFlowRequestBuilder.setCookieMask(OFConstants.DEFAULT_COOKIE_MASK);
- }
-
- MatchReactor.getInstance().convert(input.getMatch(), getVersion(), mprFlowRequestBuilder, getConvertorExecutor());
-
- return new MultipartRequestFlowCaseBuilder()
- .setMultipartRequestFlow(mprFlowRequestBuilder.build())
- .build();
- }
-
- @Override
- protected GetFlowStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
- final List<FlowAndStatisticsMapList> statsList = new ArrayList<>();
-
- if (success) {
- for (final MultipartReply mpReply : input) {
- final MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) mpReply.getMultipartReplyBody();
- final MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
- final Optional<List<FlowAndStatisticsMapList>> statsListPart = getConvertorExecutor().convert(
- replyBody.getFlowStats(), data);
-
- if (statsListPart.isPresent()) {
- for (final FlowAndStatisticsMapList part : statsListPart.get()) {
- final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId flowId =
- new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId(generateFlowId(part).getValue());
-
- statsList.add(new FlowAndStatisticsMapListBuilder(part)
- .setKey(new FlowAndStatisticsMapListKey(flowId))
- .setFlowId(flowId)
- .build());
- }
- }
- }
- }
-
- return new GetFlowStatisticsOutputBuilder()
- .setFlowAndStatisticsMapList(statsList)
- .build();
- }
-
- @Override
- protected void storeStatistics(GetFlowStatisticsOutput output) throws Exception {
- final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
-
- for (final FlowAndStatisticsMapList flowStatistics : output.getFlowAndStatisticsMapList()) {
- final FlowId flowId = generateFlowId(flowStatistics);
- final FlowKey flowKey = new FlowKey(flowId);
-
- final FlowStatisticsDataBuilder flowStatisticsDataBld = new FlowStatisticsDataBuilder()
- .setFlowStatistics(new FlowStatisticsBuilder(flowStatistics).build());
-
- final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics)
- .addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build())
- .setKey(flowKey);
-
- final InstanceIdentifier<Flow> flowStatisticsPath = nodePath
- .child(Table.class, new TableKey(flowStatistics.getTableId()))
- .child(Flow.class, flowKey);
-
- getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, flowStatisticsPath, flowBuilder.build());
- }
- }
-
- private FlowId generateFlowId(FlowAndStatisticsMapList flowStatistics) {
- final FlowStatisticsDataBuilder flowStatisticsDataBld = new FlowStatisticsDataBuilder()
- .setFlowStatistics(new FlowStatisticsBuilder(flowStatistics).build());
-
- final FlowBuilder flowBuilder = new FlowBuilder(flowStatistics)
- .addAugmentation(FlowStatisticsData.class, flowStatisticsDataBld.build());
-
- final FlowRegistryKey flowRegistryKey = FlowRegistryKeyFactory.create(getVersion(), flowBuilder.build());
- return getDeviceRegistry().getDeviceFlowRegistry().storeIfNecessary(flowRegistryKey);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.statistics.GroupStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * The Group direct statistics service.
- */
-public class GroupDirectStatisticsService extends AbstractDirectStatisticsService<GetGroupStatisticsInput, GetGroupStatisticsOutput> {
- private final VersionConvertorData data;
-
- /**
- * Instantiates a new Group direct statistics service.
- * @param requestContextStack the request context stack
- * @param deviceContext the device context
- * @param convertorExecutor
- */
- public GroupDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) {
- super(MultipartType.OFPMPGROUP, requestContextStack, deviceContext, convertorExecutor);
- data = new VersionConvertorData(getVersion());
- }
-
- @Override
- protected MultipartRequestBody buildRequestBody(GetGroupStatisticsInput input) {
- final MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder();
-
- if (input.getGroupId() != null) {
- mprGroupBuild.setGroupId(new GroupId(input.getGroupId().getValue()));
- } else {
- mprGroupBuild.setGroupId(new GroupId(OFConstants.OFPG_ALL));
- }
-
- return new MultipartRequestGroupCaseBuilder()
- .setMultipartRequestGroup(mprGroupBuild.build())
- .build();
- }
-
- @Override
- protected GetGroupStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
- final List<GroupStats> groupStats = new ArrayList<>();
-
- if (success) {
- for (final MultipartReply mpReply : input) {
- final MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) mpReply.getMultipartReplyBody();
- final MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
- final Optional<List<GroupStats>> groupStatsList = getConvertorExecutor().convert(
- replyBody.getGroupStats(), data);
-
- if (groupStatsList.isPresent()) {
- groupStats.addAll(groupStatsList.get());
- }
- }
- }
-
- return new GetGroupStatisticsOutputBuilder()
- .setGroupStats(groupStats)
- .build();
- }
-
- @Override
- protected void storeStatistics(GetGroupStatisticsOutput output) throws Exception {
- final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
-
- for (final GroupStats groupStatistics : output.getGroupStats()) {
- final InstanceIdentifier<GroupStatistics> groupStatisticsPath = nodePath
- .child(Group.class, new GroupKey(groupStatistics.getGroupId()))
- .augmentation(NodeGroupStatistics.class)
- .child(GroupStatistics.class);
-
- final GroupStatistics stats = new GroupStatisticsBuilder(groupStatistics).build();
- getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, groupStatisticsPath, stats);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * The Meter direct statistics service.
- */
-public class MeterDirectStatisticsService extends AbstractDirectStatisticsService<GetMeterStatisticsInput, GetMeterStatisticsOutput> {
- private final VersionConvertorData data;
-
- /**
- * Instantiates a new Meter direct statistics service.
- * @param requestContextStack the request context stack
- * @param deviceContext the device context
- * @param convertorExecutor
- */
- public MeterDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) {
- super(MultipartType.OFPMPMETER, requestContextStack, deviceContext, convertorExecutor);
- data = new VersionConvertorData(getVersion());
- }
-
- @Override
- protected MultipartRequestBody buildRequestBody(GetMeterStatisticsInput input) {
- final MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder();
-
- if (input.getMeterId() != null) {
- mprMeterBuild.setMeterId(new MeterId(input.getMeterId().getValue()));
- } else {
- mprMeterBuild.setMeterId(new MeterId(OFConstants.OFPM_ALL));
- }
-
- return new MultipartRequestMeterCaseBuilder()
- .setMultipartRequestMeter(mprMeterBuild.build())
- .build();
- }
-
- @Override
- protected GetMeterStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
- final List<MeterStats> meterStats = new ArrayList<>();
-
- if (success) {
- for (final MultipartReply mpReply : input) {
- final MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) mpReply.getMultipartReplyBody();
- final MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
- final Optional<List<MeterStats>> meterStatsList = getConvertorExecutor().convert(replyBody.getMeterStats(), data);
-
- if (meterStatsList.isPresent()) {
- meterStats.addAll(meterStatsList.get());
- }
- }
- }
-
- return new GetMeterStatisticsOutputBuilder()
- .setMeterStats(meterStats)
- .build();
- }
-
- @Override
- protected void storeStatistics(GetMeterStatisticsOutput output) throws Exception {
- final InstanceIdentifier<FlowCapableNode> nodePath = getDeviceInfo().getNodeInstanceIdentifier().augmentation(FlowCapableNode.class);
-
- for (final MeterStats meterStatistics : output.getMeterStats()) {
- final InstanceIdentifier<MeterStatistics> meterPath = nodePath
- .child(Meter.class, new MeterKey(meterStatistics.getMeterId()))
- .augmentation(NodeMeterStatistics.class)
- .child(MeterStatistics.class);
-
- final MeterStatistics stats = new MeterStatisticsBuilder(meterStatistics).build();
- getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, meterPath, stats);
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.flow.capable.node.connector.statistics.FlowCapableNodeConnectorStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * The Node connector direct statistics service.
- */
-public class NodeConnectorDirectStatisticsService extends AbstractDirectStatisticsService<GetNodeConnectorStatisticsInput, GetNodeConnectorStatisticsOutput> {
- /**
- * Instantiates a new Node connector direct statistics service.
- * @param requestContextStack the request context stack
- * @param deviceContext the device context
- * @param convertorExecutor
- */
- public NodeConnectorDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) {
- super(MultipartType.OFPMPPORTSTATS, requestContextStack, deviceContext, convertorExecutor);
- }
-
- @Override
- protected MultipartRequestBody buildRequestBody(GetNodeConnectorStatisticsInput input) {
- final MultipartRequestPortStatsBuilder mprPortStatsBuilder = new MultipartRequestPortStatsBuilder();
-
- if (input.getNodeConnectorId() != null) {
- mprPortStatsBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(getOfVersion(), input.getNodeConnectorId()));
- } else {
- mprPortStatsBuilder.setPortNo(OFConstants.OFPP_ANY);
- }
-
- return new MultipartRequestPortStatsCaseBuilder()
- .setMultipartRequestPortStats(mprPortStatsBuilder.build())
- .build();
- }
-
- @Override
- protected GetNodeConnectorStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
- final List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsAndPortNumberMap = new ArrayList<>();
-
- if (success) {
- for (final MultipartReply mpReply : input) {
- final MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) mpReply.getMultipartReplyBody();
- final MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
-
- for (final PortStats portStats : replyBody.getPortStats()) {
- final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
- getDatapathId(), portStats.getPortNo(), getOfVersion());
-
- final BytesBuilder bytesBuilder = new BytesBuilder()
- .setReceived(portStats.getRxBytes())
- .setTransmitted(portStats.getTxBytes());
-
- final PacketsBuilder packetsBuilder = new PacketsBuilder()
- .setReceived(portStats.getRxPackets())
- .setTransmitted(portStats.getTxPackets());
-
- final DurationBuilder durationBuilder = new DurationBuilder();
-
- if (portStats.getDurationSec() != null) {
- durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
- }
-
- if (portStats.getDurationNsec() != null) {
- durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
- }
-
- final NodeConnectorStatisticsAndPortNumberMap stats = new NodeConnectorStatisticsAndPortNumberMapBuilder()
- .setBytes(bytesBuilder.build())
- .setPackets(packetsBuilder.build())
- .setNodeConnectorId(nodeConnectorId)
- .setDuration(durationBuilder.build())
- .setCollisionCount(portStats.getCollisions())
- .setKey(new NodeConnectorStatisticsAndPortNumberMapKey(nodeConnectorId))
- .setReceiveCrcError(portStats.getRxCrcErr()).setReceiveDrops(portStats.getRxDropped())
- .setReceiveErrors(portStats.getRxErrors())
- .setReceiveFrameError(portStats.getRxFrameErr())
- .setReceiveOverRunError(portStats.getRxOverErr())
- .setTransmitDrops(portStats.getTxDropped())
- .setTransmitErrors(portStats.getTxErrors())
- .build();
-
- nodeConnectorStatisticsAndPortNumberMap.add(stats);
- }
- }
- }
-
- return new GetNodeConnectorStatisticsOutputBuilder()
- .setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatisticsAndPortNumberMap)
- .build();
- }
-
- @Override
- protected void storeStatistics(GetNodeConnectorStatisticsOutput output) throws Exception {
- final InstanceIdentifier<Node> nodePath = getDeviceInfo().getNodeInstanceIdentifier();
-
- for (final NodeConnectorStatisticsAndPortNumberMap nodeConnectorStatistics : output.getNodeConnectorStatisticsAndPortNumberMap()) {
- final InstanceIdentifier<FlowCapableNodeConnectorStatistics> nodeConnectorPath = nodePath
- .child(NodeConnector.class, new NodeConnectorKey(nodeConnectorStatistics.getNodeConnectorId()))
- .augmentation(FlowCapableNodeConnectorStatisticsData.class)
- .child(FlowCapableNodeConnectorStatistics.class);
-
- final FlowCapableNodeConnectorStatistics stats = new FlowCapableNodeConnectorStatisticsBuilder(nodeConnectorStatistics).build();
- getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, nodeConnectorPath, stats);
- }
- }
-}
package org.opendaylight.openflowplugin.impl.statistics.services.direct;
-import java.util.Optional;
import java.util.concurrent.Future;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
}
@Override
+ @SuppressWarnings("unchecked")
public Future<RpcResult<GetGroupStatisticsOutput>> getGroupStatistics(GetGroupStatisticsInput input) {
- final Optional<GroupDirectStatisticsService> service = provider.lookup(GroupDirectStatisticsService.class);
-
- if (!service.isPresent()) {
- return missingImplementation(GroupDirectStatisticsService.class);
- }
-
- return service.get().handleAndReply(input);
+ return provider.lookup(AbstractGroupDirectStatisticsService.class)
+ .map(service -> service.handleAndReply(input))
+ .orElse(missingImplementation(AbstractGroupDirectStatisticsService.class));
}
@Override
+ @SuppressWarnings("unchecked")
public Future<RpcResult<GetQueueStatisticsOutput>> getQueueStatistics(GetQueueStatisticsInput input) {
- final Optional<QueueDirectStatisticsService> service = provider.lookup(QueueDirectStatisticsService.class);
-
- if (!service.isPresent()) {
- return missingImplementation(QueueDirectStatisticsService.class);
- }
-
- return service.get().handleAndReply(input);
+ return provider.lookup(AbstractQueueDirectStatisticsService.class)
+ .map(service -> service.handleAndReply(input))
+ .orElse(missingImplementation(AbstractQueueDirectStatisticsService.class));
}
@Override
+ @SuppressWarnings("unchecked")
public Future<RpcResult<GetFlowStatisticsOutput>> getFlowStatistics(GetFlowStatisticsInput input) {
- final Optional<FlowDirectStatisticsService> service = provider.lookup(FlowDirectStatisticsService.class);
-
- if (!service.isPresent()) {
- return missingImplementation(FlowDirectStatisticsService.class);
- }
-
- return service.get().handleAndReply(input);
+ return provider.lookup(AbstractFlowDirectStatisticsService.class)
+ .map(service -> service.handleAndReply(input))
+ .orElse(missingImplementation(AbstractFlowDirectStatisticsService.class));
}
@Override
+ @SuppressWarnings("unchecked")
public Future<RpcResult<GetMeterStatisticsOutput>> getMeterStatistics(GetMeterStatisticsInput input) {
- final Optional<MeterDirectStatisticsService> service = provider.lookup(MeterDirectStatisticsService.class);
-
- if (!service.isPresent()) {
- return missingImplementation(MeterDirectStatisticsService.class);
- }
-
- return service.get().handleAndReply(input);
+ return provider.lookup(AbstractMeterDirectStatisticsService.class)
+ .map(service -> service.handleAndReply(input))
+ .orElse(missingImplementation(AbstractMeterDirectStatisticsService.class));
}
@Override
+ @SuppressWarnings("unchecked")
public Future<RpcResult<GetNodeConnectorStatisticsOutput>> getNodeConnectorStatistics(GetNodeConnectorStatisticsInput input) {
- final Optional<NodeConnectorDirectStatisticsService> service = provider.lookup(NodeConnectorDirectStatisticsService.class);
-
- if (!service.isPresent()) {
- return missingImplementation(NodeConnectorDirectStatisticsService.class);
- }
-
- return service.get().handleAndReply(input);
+ return provider.lookup(AbstractPortDirectStatisticsService.class)
+ .map(service -> service.handleAndReply(input))
+ .orElse(missingImplementation(AbstractPortDirectStatisticsService.class));
}
- private <T extends DataObject> Future<RpcResult<T>> missingImplementation(Class service) {
+ private static <T extends DataObject> Future<RpcResult<T>> missingImplementation(Class service) {
return RpcResultBuilder.<T>failed().withError(
RpcError.ErrorType.APPLICATION,
String.format("No implementation found for direct statistics service %s.", service.getCanonicalName()))
* @param service the service instance
*/
public void register(Class<? extends AbstractDirectStatisticsService> type, AbstractDirectStatisticsService service) {
- if (services.containsKey(type)) return;
-
services.put(type, service);
}
/**
* Lookup direct statistics service.
*
- * @param <T> the type parameter
* @param type the service type
* @return the service instance
*/
- public <T extends AbstractDirectStatisticsService> Optional<T> lookup(Class<T> type) {
- if (!services.containsKey(type)) return Optional.empty();
-
- return Optional.of(type.cast(services.get(type)));
+ public Optional<? extends AbstractDirectStatisticsService> lookup(Class<? extends AbstractDirectStatisticsService> type) {
+ return Optional.ofNullable(services.get(type)).map(type::cast);
}
}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.flow.capable.node.connector.queue.statistics.FlowCapableNodeConnectorQueueStatisticsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-/**
- * The Queue direct statistics service.
- */
-public class QueueDirectStatisticsService extends AbstractDirectStatisticsService<GetQueueStatisticsInput, GetQueueStatisticsOutput> {
- /**
- * Instantiates a new Queue direct statistics service.
- * @param requestContextStack the request context stack
- * @param deviceContext the device context
- * @param convertorExecutor
- */
- public QueueDirectStatisticsService(RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) {
- super(MultipartType.OFPMPQUEUE, requestContextStack, deviceContext, convertorExecutor);
- }
-
- @Override
- protected MultipartRequestBody buildRequestBody(GetQueueStatisticsInput input) {
- final MultipartRequestQueueBuilder mprQueueBuilder = new MultipartRequestQueueBuilder();
-
- if (input.getQueueId() != null) {
- mprQueueBuilder.setQueueId(input.getQueueId().getValue());
- } else {
- mprQueueBuilder.setQueueId(OFConstants.OFPQ_ALL);
- }
-
- if (input.getNodeConnectorId() != null) {
- mprQueueBuilder.setPortNo(InventoryDataServiceUtil.portNumberfromNodeConnectorId(getOfVersion(), input.getNodeConnectorId()));
- } else {
- mprQueueBuilder.setPortNo(OFConstants.OFPP_ANY);
- }
-
- return new MultipartRequestQueueCaseBuilder()
- .setMultipartRequestQueue(mprQueueBuilder.build())
- .build();
- }
-
- @Override
- protected GetQueueStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
- final List<QueueIdAndStatisticsMap> queueIdAndStatisticsMap = new ArrayList<>();
-
- if (success) {
- for (final MultipartReply mpReply : input) {
- final MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) mpReply.getMultipartReplyBody();
- final MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
-
- for (final QueueStats queueStats : replyBody.getQueueStats()) {
- final DurationBuilder durationBuilder = new DurationBuilder()
- .setSecond(new Counter32(queueStats.getDurationSec()))
- .setNanosecond(new Counter32(queueStats.getDurationNsec()));
-
- final QueueIdAndStatisticsMapBuilder statsBuilder = new QueueIdAndStatisticsMapBuilder()
- .setNodeConnectorId(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
- getDatapathId(), queueStats.getPortNo(), getOfVersion()))
- .setTransmissionErrors(new Counter64(queueStats.getTxErrors()))
- .setTransmittedBytes(new Counter64(queueStats.getTxBytes()))
- .setTransmittedPackets(new Counter64(queueStats.getTxPackets()))
- .setQueueId(new QueueId(queueStats.getQueueId()))
- .setDuration(durationBuilder.build());
-
- queueIdAndStatisticsMap.add(statsBuilder.build());
- }
- }
- }
-
- return new GetQueueStatisticsOutputBuilder()
- .setQueueIdAndStatisticsMap(queueIdAndStatisticsMap)
- .build();
- }
-
- @Override
- protected void storeStatistics(GetQueueStatisticsOutput output) throws Exception {
- final InstanceIdentifier<Node> nodePath = getDeviceInfo().getNodeInstanceIdentifier();
-
- for (final QueueIdAndStatisticsMap queueStatistics : output.getQueueIdAndStatisticsMap()) {
- if (queueStatistics.getQueueId() != null) {
- final QueueKey qKey = new QueueKey(queueStatistics.getQueueId());
-
- final FlowCapableNodeConnectorQueueStatistics statChild =
- new FlowCapableNodeConnectorQueueStatisticsBuilder(queueStatistics).build();
-
- final FlowCapableNodeConnectorQueueStatisticsDataBuilder statBuild =
- new FlowCapableNodeConnectorQueueStatisticsDataBuilder()
- .setFlowCapableNodeConnectorQueueStatistics(statChild);
-
- final InstanceIdentifier<Queue> queueStatisticsPath = nodePath
- .child(NodeConnector.class, new NodeConnectorKey(queueStatistics.getNodeConnectorId()))
- .augmentation(FlowCapableNodeConnector.class)
- .child(Queue.class, qKey);
-
- final Queue stats = new QueueBuilder()
- .setKey(qKey)
- .setQueueId(queueStatistics.getQueueId())
- .addAugmentation(FlowCapableNodeConnectorQueueStatisticsData.class, statBuild.build()).build();
-
- getTxFacade().writeToTransactionWithParentsSlow(LogicalDatastoreType.OPERATIONAL, queueStatisticsPath, stats);
- }
- }
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractFlowDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.FlowStatsResponseConvertorData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
+
+public class FlowDirectStatisticsService extends AbstractFlowDirectStatisticsService<MultipartReply> {
+
+ private final FlowStatsResponseConvertorData data;
+
+ public FlowDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ data = new FlowStatsResponseConvertorData(getVersion());
+ data.setDatapathId(getDatapathId());
+ data.setMatchPath(MatchPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_MATCH);
+ }
+
+ @Override
+ protected GetFlowStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ final List<FlowAndStatisticsMapList> statsList = new ArrayList<>();
+
+ if (success) {
+ for (final MultipartReply mpReply : input) {
+ final MultipartReplyFlowCase caseBody = (MultipartReplyFlowCase) mpReply.getMultipartReplyBody();
+ final MultipartReplyFlow replyBody = caseBody.getMultipartReplyFlow();
+ final Optional<List<FlowAndStatisticsMapList>> statsListPart = getConvertorExecutor().convert(
+ replyBody.getFlowStats(), data);
+
+ if (statsListPart.isPresent()) {
+ for (final FlowAndStatisticsMapList part : statsListPart.get()) {
+ final FlowId flowId = new FlowId(generateFlowId(part).getValue());
+ statsList.add(new FlowAndStatisticsMapListBuilder(part)
+ .setKey(new FlowAndStatisticsMapListKey(flowId))
+ .setFlowId(flowId)
+ .build());
+ }
+ }
+ }
+ }
+
+ return new GetFlowStatisticsOutputBuilder()
+ .setFlowAndStatisticsMapList(statsList)
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractGroupDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
+
+public class GroupDirectStatisticsService extends AbstractGroupDirectStatisticsService<MultipartReply> {
+
+ private final VersionConvertorData data;
+
+ public GroupDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ data = new VersionConvertorData(getVersion());
+ }
+
+ @Override
+ protected GetGroupStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ final List<GroupStats> groupStats = new ArrayList<>();
+
+ if (success) {
+ for (final MultipartReply mpReply : input) {
+ final MultipartReplyGroupCase caseBody = (MultipartReplyGroupCase) mpReply.getMultipartReplyBody();
+ final MultipartReplyGroup replyBody = caseBody.getMultipartReplyGroup();
+ final Optional<List<GroupStats>> groupStatsList = getConvertorExecutor().convert(
+ replyBody.getGroupStats(), data);
+
+ groupStatsList.ifPresent(groupStats::addAll);
+ }
+ }
+
+ return new GetGroupStatisticsOutputBuilder()
+ .setGroupStats(groupStats)
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractMeterDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
+
+public class MeterDirectStatisticsService extends AbstractMeterDirectStatisticsService<MultipartReply> {
+
+ private final VersionConvertorData data;
+
+ public MeterDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ data = new VersionConvertorData(getVersion());
+ }
+
+ @Override
+ protected GetMeterStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ final List<MeterStats> meterStats = new ArrayList<>();
+
+ if (success) {
+ for (final MultipartReply mpReply : input) {
+ final MultipartReplyMeterCase caseBody = (MultipartReplyMeterCase) mpReply.getMultipartReplyBody();
+ final MultipartReplyMeter replyBody = caseBody.getMultipartReplyMeter();
+ final Optional<List<MeterStats>> meterStatsList = getConvertorExecutor().convert(replyBody.getMeterStats(), data);
+ meterStatsList.ifPresent(meterStats::addAll);
+ }
+ }
+
+ return new GetMeterStatisticsOutputBuilder()
+ .setMeterStats(meterStats)
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractFlowDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractGroupDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractMeterDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractPortDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractQueueDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+
+/**
+ * Utility class for instantiating #{@link org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider}
+ * with all multi-layer services already in
+ */
+public class MultiLayerDirectStatisticsProviderInitializer {
+
+ public static OpendaylightDirectStatisticsServiceProvider createProvider(
+ final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+
+ final OpendaylightDirectStatisticsServiceProvider provider = new OpendaylightDirectStatisticsServiceProvider();
+
+ provider.register(AbstractFlowDirectStatisticsService.class, new FlowDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+ provider.register(AbstractGroupDirectStatisticsService.class, new FlowDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+ provider.register(AbstractMeterDirectStatisticsService.class, new MeterDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+ provider.register(AbstractPortDirectStatisticsService.class, new PortDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+ provider.register(AbstractQueueDirectStatisticsService.class, new QueueDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+
+ return provider;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractPortDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.BytesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.node.connector.statistics.PacketsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMapKey;
+
+public class PortDirectStatisticsService extends AbstractPortDirectStatisticsService<MultipartReply> {
+
+ public PortDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ protected GetNodeConnectorStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ final List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsAndPortNumberMap = new ArrayList<>();
+
+ if (success) {
+ for (final MultipartReply mpReply : input) {
+ final MultipartReplyPortStatsCase caseBody = (MultipartReplyPortStatsCase) mpReply.getMultipartReplyBody();
+ final MultipartReplyPortStats replyBody = caseBody.getMultipartReplyPortStats();
+
+ for (final PortStats portStats : replyBody.getPortStats()) {
+ final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
+ getDatapathId(), portStats.getPortNo(), getOfVersion());
+
+ final BytesBuilder bytesBuilder = new BytesBuilder()
+ .setReceived(portStats.getRxBytes())
+ .setTransmitted(portStats.getTxBytes());
+
+ final PacketsBuilder packetsBuilder = new PacketsBuilder()
+ .setReceived(portStats.getRxPackets())
+ .setTransmitted(portStats.getTxPackets());
+
+ final DurationBuilder durationBuilder = new DurationBuilder();
+
+ if (portStats.getDurationSec() != null) {
+ durationBuilder.setSecond(new Counter32(portStats.getDurationSec()));
+ }
+
+ if (portStats.getDurationNsec() != null) {
+ durationBuilder.setNanosecond(new Counter32(portStats.getDurationNsec()));
+ }
+
+ final NodeConnectorStatisticsAndPortNumberMap stats = new NodeConnectorStatisticsAndPortNumberMapBuilder()
+ .setBytes(bytesBuilder.build())
+ .setPackets(packetsBuilder.build())
+ .setNodeConnectorId(nodeConnectorId)
+ .setDuration(durationBuilder.build())
+ .setCollisionCount(portStats.getCollisions())
+ .setKey(new NodeConnectorStatisticsAndPortNumberMapKey(nodeConnectorId))
+ .setReceiveCrcError(portStats.getRxCrcErr()).setReceiveDrops(portStats.getRxDropped())
+ .setReceiveErrors(portStats.getRxErrors())
+ .setReceiveFrameError(portStats.getRxFrameErr())
+ .setReceiveOverRunError(portStats.getRxOverErr())
+ .setTransmitDrops(portStats.getTxDropped())
+ .setTransmitErrors(portStats.getTxErrors())
+ .build();
+
+ nodeConnectorStatisticsAndPortNumberMap.add(stats);
+ }
+ }
+ }
+
+ return new GetNodeConnectorStatisticsOutputBuilder()
+ .setNodeConnectorStatisticsAndPortNumberMap(nodeConnectorStatisticsAndPortNumberMap)
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractQueueDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.queue.id.and.statistics.map.QueueIdAndStatisticsMapKey;
+
+public class QueueDirectStatisticsService extends AbstractQueueDirectStatisticsService<MultipartReply> {
+
+ public QueueDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ protected GetQueueStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ final List<QueueIdAndStatisticsMap> queueIdAndStatisticsMap = new ArrayList<>();
+
+ if (success) {
+ for (final MultipartReply mpReply : input) {
+ final MultipartReplyQueueCase caseBody = (MultipartReplyQueueCase) mpReply.getMultipartReplyBody();
+ final MultipartReplyQueue replyBody = caseBody.getMultipartReplyQueue();
+
+ for (final QueueStats queueStats : replyBody.getQueueStats()) {
+ final DurationBuilder durationBuilder = new DurationBuilder()
+ .setSecond(new Counter32(queueStats.getDurationSec()))
+ .setNanosecond(new Counter32(queueStats.getDurationNsec()));
+
+ final QueueId queueId = new QueueId(queueStats.getQueueId());
+ final NodeConnectorId nodeConnectorId = InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(
+ getDatapathId(), queueStats.getPortNo(), getOfVersion());
+
+ final QueueIdAndStatisticsMapBuilder statsBuilder = new QueueIdAndStatisticsMapBuilder()
+ .setKey(new QueueIdAndStatisticsMapKey(nodeConnectorId, queueId))
+ .setNodeConnectorId(nodeConnectorId)
+ .setTransmissionErrors(new Counter64(queueStats.getTxErrors()))
+ .setTransmittedBytes(new Counter64(queueStats.getTxBytes()))
+ .setTransmittedPackets(new Counter64(queueStats.getTxPackets()))
+ .setQueueId(queueId)
+ .setDuration(durationBuilder.build());
+
+ queueIdAndStatisticsMap.add(statsBuilder.build());
+ }
+ }
+ }
+
+ return new GetQueueStatisticsOutputBuilder()
+ .setQueueIdAndStatisticsMap(queueIdAndStatisticsMap)
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractFlowDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+
+public class FlowDirectStatisticsService extends AbstractFlowDirectStatisticsService<MultipartReply> {
+
+ public FlowDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider); }
+
+ @Override
+ protected GetFlowStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ return new GetFlowStatisticsOutputBuilder()
+ .setFlowAndStatisticsMapList(input
+ .stream()
+ .flatMap(multipartReply -> MultipartReplyFlowStats.class
+ .cast(multipartReply.getMultipartReplyBody())
+ .getFlowAndStatisticsMapList()
+ .stream())
+ .map(flowAndStatisticsMapList -> {
+ final FlowId flowId = new FlowId(generateFlowId(flowAndStatisticsMapList));
+ return new FlowAndStatisticsMapListBuilder(flowAndStatisticsMapList)
+ .setKey(new FlowAndStatisticsMapListKey(flowId))
+ .setFlowId(flowId)
+ .build();
+ })
+ .collect(Collectors.toList()))
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractGroupDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyGroupStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+
+public class GroupDirectStatisticsService extends AbstractGroupDirectStatisticsService<MultipartReply> {
+
+ public GroupDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ protected GetGroupStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ return new GetGroupStatisticsOutputBuilder()
+ .setGroupStats(input
+ .stream()
+ .flatMap(multipartReply -> MultipartReplyGroupStats.class
+ .cast(multipartReply.getMultipartReplyBody())
+ .getGroupStats()
+ .stream())
+ .collect(Collectors.toList()))
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractMeterDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+
+public class MeterDirectStatisticsService extends AbstractMeterDirectStatisticsService<MultipartReply> {
+
+ public MeterDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ protected GetMeterStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ return new GetMeterStatisticsOutputBuilder()
+ .setMeterStats(input
+ .stream()
+ .flatMap(multipartReply -> MultipartReplyMeterStats.class
+ .cast(multipartReply.getMultipartReplyBody())
+ .getMeterStats()
+ .stream())
+ .collect(Collectors.toList()))
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractPortDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.multipart.reply.multipart.reply.body.MultipartReplyPortStats;
+
+public class PortDirectStatisticsService extends AbstractPortDirectStatisticsService<MultipartReply> {
+
+ public PortDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ protected GetNodeConnectorStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ return new GetNodeConnectorStatisticsOutputBuilder()
+ .setNodeConnectorStatisticsAndPortNumberMap(input
+ .stream()
+ .flatMap(multipartReply -> MultipartReplyPortStats.class
+ .cast(multipartReply.getMultipartReplyBody())
+ .getNodeConnectorStatisticsAndPortNumberMap()
+ .stream())
+ .collect(Collectors.toList()))
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractQueueDirectStatisticsService;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.MultipartReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.multipart.reply.multipart.reply.body.MultipartReplyQueueStats;
+
+public class QueueDirectStatisticsService extends AbstractQueueDirectStatisticsService<MultipartReply> {
+
+ public QueueDirectStatisticsService(final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+ super(requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider);
+ }
+
+ @Override
+ protected GetQueueStatisticsOutput buildReply(List<MultipartReply> input, boolean success) {
+ return new GetQueueStatisticsOutputBuilder()
+ .setQueueIdAndStatisticsMap(input
+ .stream()
+ .flatMap(multipartReply -> MultipartReplyQueueStats.class
+ .cast(multipartReply.getMultipartReplyBody())
+ .getQueueIdAndStatisticsMap()
+ .stream())
+ .collect(Collectors.toList()))
+ .build();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer;
+
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractFlowDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractGroupDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractMeterDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractPortDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractQueueDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
+
+/**
+ * Utility class for instantiating #{@link org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider}
+ * with all multi-layer services already in
+ */
+public class SingleLayerDirectStatisticsProviderInitializer {
+
+ public static OpendaylightDirectStatisticsServiceProvider createProvider(
+ final RequestContextStack requestContextStack,
+ final DeviceContext deviceContext,
+ final ConvertorExecutor convertorExecutor,
+ final MultipartWriterProvider statisticsWriterProvider) {
+
+ final OpendaylightDirectStatisticsServiceProvider provider = new OpendaylightDirectStatisticsServiceProvider();
+
+ provider.register(AbstractFlowDirectStatisticsService.class, new FlowDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+ provider.register(AbstractGroupDirectStatisticsService.class, new FlowDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+ provider.register(AbstractMeterDirectStatisticsService.class, new MeterDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+ provider.register(AbstractPortDirectStatisticsService.class, new PortDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+ provider.register(AbstractQueueDirectStatisticsService.class, new QueueDirectStatisticsService(
+ requestContextStack, deviceContext, convertorExecutor, statisticsWriterProvider));
+
+ return provider;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.openflowplugin.impl.util;
+
+import java.net.InetSocketAddress;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.SwitchFeaturesUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.flow.node.SwitchFeatures;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DeviceInitializationUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DeviceInitializationUtil.class);
+
+ private DeviceInitializationUtil() {
+ // Hiding implicit constructor
+ }
+
+ /**
+ * Create specified number of empty tables on device
+ * FIXME: remove after ovs table features fix
+ * @param txFacade transaction facade
+ * @param deviceInfo device info
+ * @param nrOfTables number of tables
+ */
+ public static void makeEmptyTables(final TxFacade txFacade, final DeviceInfo deviceInfo, final Short nrOfTables) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("About to create {} empty tables for node {}.", nrOfTables, deviceInfo.getLOGValue());
+ }
+
+ for (int i = 0; i < nrOfTables; i++) {
+ try {
+ txFacade.writeToTransaction(LogicalDatastoreType.OPERATIONAL,
+ deviceInfo
+ .getNodeInstanceIdentifier()
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey((short) i)),
+ new TableBuilder()
+ .setId((short) i)
+ .addAugmentation(
+ FlowTableStatisticsData.class,
+ new FlowTableStatisticsDataBuilder().build())
+ .build());
+ } catch (final Exception e) {
+ LOG.debug("makeEmptyTables: Failed to write node {} to DS ", deviceInfo.getLOGValue(), e);
+ }
+ }
+ }
+
+ /**
+ * Retrieve ip address from connection
+ * @param connectionContext connection context
+ * @param instanceIdentifier instance identifier
+ * @return ip adress
+ */
+ public static IpAddress getIpAddress(final ConnectionContext connectionContext,
+ final InstanceIdentifier<Node> instanceIdentifier) {
+ final InetSocketAddress remoteAddress = connectionContext
+ .getConnectionAdapter()
+ .getRemoteAddress();
+
+ if (remoteAddress == null) {
+ LOG.warn("IP address of the node {} cannot be obtained. No connection with switch.", instanceIdentifier);
+ return null;
+ }
+
+ LOG.info("IP address of the node {} is: {}", instanceIdentifier, remoteAddress);
+ return IetfInetUtil.INSTANCE.ipAddressFor(remoteAddress.getAddress());
+ }
+
+ /**
+ * Retrieve switch features from connection
+ * @param connectionContext connection context
+ * @return switch features
+ */
+ public static SwitchFeatures getSwitchFeatures(final ConnectionContext connectionContext) {
+ return SwitchFeaturesUtil
+ .getInstance()
+ .buildSwitchFeatures(new GetFeaturesOutputBuilder(connectionContext
+ .getFeatures())
+ .build());
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.util;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-import java.math.BigInteger;
-import java.net.InetSocketAddress;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
-import org.opendaylight.openflowplugin.api.ConnectionException;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
-import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
-import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
-import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
-import org.opendaylight.openflowplugin.impl.common.MultipartRequestInputFactory;
-import org.opendaylight.openflowplugin.impl.common.NodeStaticReplyTranslatorUtil;
-import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.SwitchFeaturesUtil;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.FlowTableStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDesc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeaturesKey;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class DeviceInitializationUtils {
-
- private static final Logger LOG = LoggerFactory.getLogger(DeviceInitializationUtils.class);
-
- private DeviceInitializationUtils() {
- // Hiding implicit constructor
- }
-
- /**
- * InitializationNodeInformation is good to call only for MASTER otherwise we will have not empty transaction
- * for every Cluster Node (SLAVE too) and we will get race-condition by closing Connection.
- *
- * @param deviceContext
- * @param switchFeaturesMandatory
- * @param convertorExecutor
- */
- public static void initializeNodeInformation(final DeviceContext deviceContext, final boolean switchFeaturesMandatory, final ConvertorExecutor convertorExecutor) throws ExecutionException, InterruptedException {
- Preconditions.checkArgument(deviceContext != null);
- final DeviceState deviceState = Preconditions.checkNotNull(deviceContext.getDeviceState());
- final DeviceInfo deviceInfo = deviceContext.getDeviceInfo();
- final ConnectionContext connectionContext = Preconditions.checkNotNull(deviceContext.getPrimaryConnectionContext());
- final short version = deviceInfo.getVersion();
- LOG.trace("initalizeNodeInformation for node {}", deviceInfo.getNodeId());
- final SettableFuture<Void> returnFuture = SettableFuture.create();
- addNodeToOperDS(deviceContext, returnFuture);
- final ListenableFuture<List<RpcResult<List<MultipartReply>>>> deviceFeaturesFuture;
- if (OFConstants.OFP_VERSION_1_0 == version) {
- final CapabilitiesV10 capabilitiesV10 = connectionContext.getFeatures().getCapabilitiesV10();
-
- DeviceStateUtil.setDeviceStateBasedOnV10Capabilities(deviceState, capabilitiesV10);
-
- deviceFeaturesFuture = createDeviceFeaturesForOF10(deviceContext);
- // create empty tables after device description is processed
- chainTableTrunkWriteOF10(deviceContext, deviceFeaturesFuture);
-
- final short ofVersion = deviceInfo.getVersion();
- final TranslatorKey translatorKey = new TranslatorKey(ofVersion, PortGrouping.class.getName());
- final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = deviceContext.oook()
- .lookupTranslator(translatorKey);
- final BigInteger dataPathId = deviceContext.getDeviceInfo().getDatapathId();
-
- for (final PortGrouping port : connectionContext.getFeatures().getPhyPort()) {
- final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, deviceContext.getDeviceInfo(), null);
-
- final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId(
- dataPathId.toString(), port.getPortNo(), ofVersion);
- final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder().setId(nodeConnectorId);
- ncBuilder.addAugmentation(FlowCapableNodeConnector.class, fcNodeConnector);
- ncBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class,
- new FlowCapableNodeConnectorStatisticsDataBuilder().build());
- final NodeConnector connector = ncBuilder.build();
- final InstanceIdentifier<NodeConnector> connectorII = deviceInfo.getNodeInstanceIdentifier().child(
- NodeConnector.class, connector.getKey());
- try {
- deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, connectorII, connector);
- } catch (final Exception e) {
- LOG.debug("initializeNodeInformation: Failed to write node {} to DS ", deviceInfo.getNodeId().toString(),
- e);
- }
-
- }
- } else if (OFConstants.OFP_VERSION_1_3 == version) {
- final Capabilities capabilities = connectionContext.getFeatures().getCapabilities();
- LOG.debug("Setting capabilities for device {}", deviceInfo.getNodeId());
- DeviceStateUtil.setDeviceStateBasedOnV13Capabilities(deviceState, capabilities);
- createDeviceFeaturesForOF13(deviceContext, switchFeaturesMandatory, convertorExecutor).get();
- } else {
- throw new ExecutionException(new ConnectionException("Unsupported version " + version));
- }
-
- }
-
- private static void addNodeToOperDS(final DeviceContext deviceContext, final SettableFuture<Void> future) {
- Preconditions.checkArgument(deviceContext != null);
- final NodeBuilder nodeBuilder = new NodeBuilder().setId(deviceContext.getDeviceInfo().getNodeId()).setNodeConnector(
- Collections.emptyList());
- try {
- deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(),
- nodeBuilder.build());
- } catch (final Exception e) {
- LOG.warn("addNodeToOperDS: Failed to write node {} to DS ", deviceContext.getDeviceInfo().getNodeId(), e);
- future.cancel(true);
- }
- }
-
- private static ListenableFuture<List<RpcResult<List<MultipartReply>>>> createDeviceFeaturesForOF10(
- final DeviceContext deviceContext) {
- final ListenableFuture<RpcResult<List<MultipartReply>>> replyDesc = getNodeStaticInfo(MultipartType.OFPMPDESC,
- deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
-
- return Futures.allAsList(Arrays.asList(replyDesc));
- }
-
- private static ListenableFuture<List<RpcResult<List<MultipartReply>>>> createDeviceFeaturesForOF13(
- final DeviceContext deviceContext, final boolean switchFeaturesMandatory, final ConvertorExecutor convertorExecutor) {
-
- final ListenableFuture<RpcResult<List<MultipartReply>>> replyDesc = getNodeStaticInfo(MultipartType.OFPMPDESC,
- deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
-
- //first process description reply, write data to DS and write consequent data if successful
- return Futures.transform(replyDesc,
- new AsyncFunction<RpcResult<List<MultipartReply>>, List<RpcResult<List<MultipartReply>>>>() {
- @Override
- public ListenableFuture<List<RpcResult<List<MultipartReply>>>> apply(
- final RpcResult<List<MultipartReply>> rpcResult) throws Exception {
-
- translateAndWriteReply(MultipartType.OFPMPDESC, deviceContext,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), rpcResult.getResult(), convertorExecutor);
-
- final ListenableFuture<RpcResult<List<MultipartReply>>> replyMeterFeature = getNodeStaticInfo(
- MultipartType.OFPMPMETERFEATURES, deviceContext,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
-
- createSuccessProcessingCallback(MultipartType.OFPMPMETERFEATURES, deviceContext,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyMeterFeature, convertorExecutor);
-
- final ListenableFuture<RpcResult<List<MultipartReply>>> replyGroupFeatures = getNodeStaticInfo(
- MultipartType.OFPMPGROUPFEATURES, deviceContext,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
- createSuccessProcessingCallback(MultipartType.OFPMPGROUPFEATURES, deviceContext,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyGroupFeatures, convertorExecutor);
-
- final ListenableFuture<RpcResult<List<MultipartReply>>> replyTableFeatures;
-
- if (deviceContext.isSkipTableFeatures()) {
- replyTableFeatures = RpcResultBuilder.<List<MultipartReply>>success().buildFuture();
- } else {
- replyTableFeatures = getNodeStaticInfo(
- MultipartType.OFPMPTABLEFEATURES, deviceContext,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), deviceContext.getDeviceInfo().getVersion());
- }
- createSuccessProcessingCallback(MultipartType.OFPMPTABLEFEATURES, deviceContext,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyTableFeatures, convertorExecutor);
-
- final ListenableFuture<RpcResult<List<MultipartReply>>> replyPortDescription = getNodeStaticInfo(
- MultipartType.OFPMPPORTDESC, deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(),
- deviceContext.getDeviceInfo().getVersion());
- createSuccessProcessingCallback(MultipartType.OFPMPPORTDESC, deviceContext,
- deviceContext.getDeviceInfo().getNodeInstanceIdentifier(), replyPortDescription, convertorExecutor);
- if (switchFeaturesMandatory) {
- return Futures.allAsList(Arrays.asList(replyMeterFeature, replyGroupFeatures,
- replyTableFeatures, replyPortDescription));
- } else {
- return Futures.successfulAsList(Arrays.asList(replyMeterFeature, replyGroupFeatures,
- replyTableFeatures, replyPortDescription));
- }
- }
- });
-
- }
-
- static void translateAndWriteReply(final MultipartType type, final DeviceContext dContext,
- final InstanceIdentifier<Node> nodeII, final Collection<MultipartReply> result,
- final ConvertorExecutor convertorExecutor) {
- if (Objects.nonNull(result)) {
- try {
- result.stream()
- .map(MultipartReply::getMultipartReplyBody)
- .forEach(multipartReplyBody -> {
- if (!(writeDesc(type, multipartReplyBody, dContext, nodeII)
- || writeTableFeatures(type, multipartReplyBody, dContext, nodeII, convertorExecutor)
- || writeMeterFeatures(type, multipartReplyBody, dContext, nodeII)
- || writeGroupFeatures(type, multipartReplyBody, dContext, nodeII)
- || writePortDesc(type, multipartReplyBody, dContext, nodeII))) {
- throw new IllegalArgumentException("Unexpected MultipartType " + type);
- }
- });
- } catch (final Exception e) {
- LOG.debug("translateAndWriteReply: Failed to write node {} to DS ", dContext.getDeviceInfo().getNodeId().toString(), e);
- }
- } else {
- LOG.debug("translateAndWriteReply: Failed to write node {} to DS because we failed to gather device" +
- "info.",
- dContext.getDeviceInfo().getNodeId().toString());
- }
- }
-
- private static boolean writeDesc(final MultipartType type,
- final MultipartReplyBody body,
- final DeviceContext dContext,
- final InstanceIdentifier<Node> nodeII) {
- if (!MultipartType.OFPMPDESC.equals(type)) {
- return false;
- }
-
- Preconditions.checkArgument(body instanceof MultipartReplyDescCase);
- final MultipartReplyDesc replyDesc = ((MultipartReplyDescCase) body).getMultipartReplyDesc();
- final FlowCapableNode fcNode = NodeStaticReplyTranslatorUtil
- .nodeDescTranslator(replyDesc, getIpAddressOf(dContext))
- .setSwitchFeatures(SwitchFeaturesUtil.getInstance().buildSwitchFeatures(
- new GetFeaturesOutputBuilder(dContext.getPrimaryConnectionContext().getFeatures()).build()))
- .build();
-
- final InstanceIdentifier<FlowCapableNode> fNodeII = nodeII.augmentation(FlowCapableNode.class);
- dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, fNodeII, fcNode);
- return true;
- }
-
- private static boolean writeTableFeatures(final MultipartType type,
- final MultipartReplyBody body,
- final DeviceContext dContext,
- final InstanceIdentifier<Node> nodeII,
- final ConvertorExecutor convertorExecutor) {
- if (!MultipartType.OFPMPTABLEFEATURES.equals(type)) {
- return false;
- }
-
- Preconditions.checkArgument(body instanceof MultipartReplyTableFeaturesCase);
- final MultipartReplyTableFeatures tableFeaturesMP = ((MultipartReplyTableFeaturesCase) body)
- .getMultipartReplyTableFeatures();
- final List<TableFeatures> tableFeatures = NodeStaticReplyTranslatorUtil
- .nodeTableFeatureTranslator(tableFeaturesMP, dContext.getDeviceInfo().getVersion(), convertorExecutor);
- for (final TableFeatures tableFeature : tableFeatures) {
- final Short tableId = tableFeature.getTableId();
- final KeyedInstanceIdentifier<TableFeatures, TableFeaturesKey> tableFeaturesII =
- nodeII.augmentation(FlowCapableNode.class)
- .child(TableFeatures.class, new TableFeaturesKey(tableId));
- dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableFeaturesII, tableFeature);
-
- // write parent for table statistics
- final KeyedInstanceIdentifier<Table, TableKey> tableII =
- nodeII.augmentation(FlowCapableNode.class)
- .child(Table.class, new TableKey(tableId));
- final TableBuilder tableBld = new TableBuilder().setId(tableId)
- .addAugmentation(FlowTableStatisticsData.class,
- new FlowTableStatisticsDataBuilder().build());
-
- dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableII, tableBld.build());
- }
-
- return true;
- }
-
- private static boolean writeMeterFeatures(final MultipartType type,
- final MultipartReplyBody body,
- final DeviceContext dContext,
- final InstanceIdentifier<Node> nodeII) {
- if (!MultipartType.OFPMPMETERFEATURES.equals(type)) {
- return false;
- }
-
- Preconditions.checkArgument(body instanceof MultipartReplyMeterFeaturesCase);
- final MultipartReplyMeterFeatures meterFeatures = ((MultipartReplyMeterFeaturesCase) body)
- .getMultipartReplyMeterFeatures();
- final NodeMeterFeatures mFeature = NodeStaticReplyTranslatorUtil
- .nodeMeterFeatureTranslator(meterFeatures);
- final InstanceIdentifier<NodeMeterFeatures> mFeatureII = nodeII
- .augmentation(NodeMeterFeatures.class);
- dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, mFeatureII, mFeature);
- if (0L < mFeature.getMeterFeatures().getMaxMeter().getValue()) {
- dContext.getDeviceState().setMeterAvailable(true);
- }
-
- return true;
- }
-
- private static boolean writeGroupFeatures(final MultipartType type,
- final MultipartReplyBody body,
- final DeviceContext dContext,
- final InstanceIdentifier<Node> nodeII) {
- if (!MultipartType.OFPMPGROUPFEATURES.equals(type)) {
- return false;
- }
-
- Preconditions.checkArgument(body instanceof MultipartReplyGroupFeaturesCase);
- final MultipartReplyGroupFeatures groupFeatures = ((MultipartReplyGroupFeaturesCase) body)
- .getMultipartReplyGroupFeatures();
- final NodeGroupFeatures gFeature = NodeStaticReplyTranslatorUtil
- .nodeGroupFeatureTranslator(groupFeatures);
- final InstanceIdentifier<NodeGroupFeatures> gFeatureII = nodeII
- .augmentation(NodeGroupFeatures.class);
- dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, gFeatureII, gFeature);
-
- return true;
- }
-
- private static boolean writePortDesc(final MultipartType type,
- final MultipartReplyBody body,
- final DeviceContext dContext,
- final InstanceIdentifier<Node> nodeII) {
- if (!MultipartType.OFPMPPORTDESC.equals(type)) {
- return false;
- }
-
- Preconditions.checkArgument(body instanceof MultipartReplyPortDescCase);
- final MultipartReplyPortDesc portDesc = ((MultipartReplyPortDescCase) body)
- .getMultipartReplyPortDesc();
- for (final PortGrouping port : portDesc.getPorts()) {
- final short ofVersion = dContext.getDeviceInfo().getVersion();
- final TranslatorKey translatorKey = new TranslatorKey(ofVersion, PortGrouping.class.getName());
- final MessageTranslator<PortGrouping, FlowCapableNodeConnector> translator = dContext.oook()
- .lookupTranslator(translatorKey);
- final FlowCapableNodeConnector fcNodeConnector = translator.translate(port, dContext.getDeviceInfo(), null);
-
- final BigInteger dataPathId = dContext.getPrimaryConnectionContext().getFeatures()
- .getDatapathId();
- final NodeConnectorId nodeConnectorId = NodeStaticReplyTranslatorUtil.nodeConnectorId(
- dataPathId.toString(), port.getPortNo(), ofVersion);
- final NodeConnectorBuilder ncBuilder = new NodeConnectorBuilder().setId(nodeConnectorId);
- ncBuilder.addAugmentation(FlowCapableNodeConnector.class, fcNodeConnector);
-
- ncBuilder.addAugmentation(FlowCapableNodeConnectorStatisticsData.class,
- new FlowCapableNodeConnectorStatisticsDataBuilder().build());
- final NodeConnector connector = ncBuilder.build();
-
- final InstanceIdentifier<NodeConnector> connectorII = nodeII.child(NodeConnector.class,
- connector.getKey());
- dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, connectorII, connector);
- }
-
- return true;
- }
-
- private static void createEmptyFlowCapableNodeInDs(final DeviceContext deviceContext) {
- final FlowCapableNodeBuilder flowCapableNodeBuilder = new FlowCapableNodeBuilder();
- final InstanceIdentifier<FlowCapableNode> fNodeII = deviceContext.getDeviceInfo().getNodeInstanceIdentifier()
- .augmentation(FlowCapableNode.class);
- try {
- deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, fNodeII, flowCapableNodeBuilder.build());
- } catch (final Exception e) {
- LOG.debug("createEmptyFlowCapableNodeInDs: Failed to write node {} to DS ", deviceContext.getDeviceInfo().getNodeId().toString(), e);
- }
- }
-
- private static IpAddress getIpAddressOf(final DeviceContext deviceContext) {
-
- final InetSocketAddress remoteAddress = deviceContext.getPrimaryConnectionContext().getConnectionAdapter()
- .getRemoteAddress();
-
- if (remoteAddress == null) {
- LOG.warn("IP address of the node {} cannot be obtained. No connection with switch.", deviceContext
- .getDeviceInfo().getNodeId());
- return null;
- }
- LOG.info("IP address of switch is: {}", remoteAddress);
-
- return IetfInetUtil.INSTANCE.ipAddressFor(remoteAddress.getAddress());
- }
-
- // FIXME : remove after ovs tableFeatures fix
- private static void makeEmptyTables(final DeviceContext dContext, final InstanceIdentifier<Node> nodeII,
- final Short nrOfTables) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("About to create {} empty tables.", nrOfTables);
- }
- for (int i = 0; i < nrOfTables; i++) {
- final short tId = (short) i;
- final InstanceIdentifier<Table> tableII = nodeII.augmentation(FlowCapableNode.class).child(Table.class,
- new TableKey(tId));
- final TableBuilder tableBuilder = new TableBuilder().setId(tId).addAugmentation(
- FlowTableStatisticsData.class, new FlowTableStatisticsDataBuilder().build());
-
- try {
- dContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableII, tableBuilder.build());
- } catch (final Exception e) {
- LOG.debug("makeEmptyTables: Failed to write node {} to DS ", dContext.getDeviceInfo().getNodeId().toString(), e);
- }
-
- }
- }
-
- static void createSuccessProcessingCallback(final MultipartType type, final DeviceContext deviceContext,
- final InstanceIdentifier<Node> nodeII,
- final ListenableFuture<RpcResult<List<MultipartReply>>> requestContextFuture,
- final ConvertorExecutor convertorExecutor) {
- Futures.addCallback(requestContextFuture, new FutureCallback<RpcResult<List<MultipartReply>>>() {
- @Override
- public void onSuccess(final RpcResult<List<MultipartReply>> rpcResult) {
- final List<MultipartReply> result = rpcResult.getResult();
- if (result != null) {
- LOG.info("Static node {} info: {} collected", deviceContext.getDeviceInfo().getNodeId(), type);
- translateAndWriteReply(type, deviceContext, nodeII, result, convertorExecutor);
- } else {
- for (RpcError rpcError : rpcResult.getErrors()) {
- LOG.info("Failed to retrieve static node {} info: {}", type, rpcError.getMessage());
- if (LOG.isTraceEnabled() && Objects.nonNull(rpcError.getCause())) {
- LOG.trace("Detailed error:", rpcError.getCause());
- }
- }
- if (MultipartType.OFPMPTABLEFEATURES.equals(type)) {
- makeEmptyTables(deviceContext, nodeII, deviceContext.getPrimaryConnectionContext()
- .getFeatures().getTables());
- }
- }
- }
-
- @Override
- public void onFailure(final Throwable throwable) {
- LOG.info("Request of type {} for static info of node {} failed.", type, nodeII);
- }
- });
- }
-
- private static ListenableFuture<RpcResult<List<MultipartReply>>> getNodeStaticInfo(final MultipartType type,
- final DeviceContext deviceContext,
- final InstanceIdentifier<Node> nodeII,
- final short version) {
-
- final OutboundQueue queue = deviceContext.getPrimaryConnectionContext().getOutboundQueueProvider();
-
- final Long reserved = deviceContext.getDeviceInfo().reserveXidForDeviceMessage();
- final RequestContext<List<MultipartReply>> requestContext = new AbstractRequestContext<List<MultipartReply>>(
- reserved) {
- @Override
- public void close() {
- //NOOP
- }
- };
-
- final Xid xid = requestContext.getXid();
-
- if (Objects.isNull(xid)) {
- LOG.debug("Xid is not present, so cancelling node static info gathering.");
- return Futures.immediateCancelledFuture();
- }
-
- LOG.trace("Hooking xid {} to device context - precaution.", reserved);
-
- final MultiMsgCollector multiMsgCollector = deviceContext.getMultiMsgCollector(requestContext);
- queue.commitEntry(xid.getValue(),
- MultipartRequestInputFactory.makeMultipartRequestInput(xid.getValue(), version, type),
- new FutureCallback<OfHeader>() {
- @Override
- public void onSuccess(final OfHeader ofHeader) {
- if (ofHeader instanceof MultipartReply) {
- final MultipartReply multipartReply = (MultipartReply) ofHeader;
- multiMsgCollector.addMultipartMsg(multipartReply);
- } else if (null != ofHeader) {
- LOG.info("Unexpected response type received {}.", ofHeader.getClass());
- } else {
- multiMsgCollector.endCollecting();
- LOG.info("Response received is null.");
- }
- }
-
- @Override
- public void onFailure(final Throwable t) {
- LOG.info("Fail response from OutboundQueue for multipart type {}.", type);
- final RpcResult<List<MultipartReply>> rpcResult = RpcResultBuilder
- .<List<MultipartReply>>failed().build();
- requestContext.setResult(rpcResult);
- if (MultipartType.OFPMPTABLEFEATURES.equals(type)) {
- makeEmptyTables(deviceContext, nodeII, deviceContext.getPrimaryConnectionContext()
- .getFeatures().getTables());
- }
- requestContext.close();
- }
- });
-
- return requestContext.getFuture();
- }
-
- static void chainTableTrunkWriteOF10(final DeviceContext deviceContext,
- final ListenableFuture<List<RpcResult<List<MultipartReply>>>> deviceFeaturesFuture) {
-
- try {
- if (LOG.isTraceEnabled()) {
- LOG.trace("Waiting for protocol version 1.0");
- }
- List<RpcResult<List<MultipartReply>>> results = deviceFeaturesFuture.get();
- boolean allSucceeded = true;
- for (final RpcResult<List<MultipartReply>> rpcResult : results) {
- allSucceeded &= rpcResult.isSuccessful();
- }
- if (allSucceeded) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Creating empty flow capable node: {}", deviceContext.getDeviceInfo().getLOGValue());
- }
- createEmptyFlowCapableNodeInDs(deviceContext);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Creating empty tables for {}", deviceContext.getDeviceInfo().getLOGValue());
- }
- makeEmptyTables(deviceContext, deviceContext.getDeviceInfo().getNodeInstanceIdentifier(),
- deviceContext.getPrimaryConnectionContext().getFeatures().getTables());
- }
- } catch (InterruptedException | ExecutionException e) {
- LOG.warn("Error occurred in preparation node {} for protocol 1.0", deviceContext.getDeviceInfo().getLOGValue());
- if (LOG.isTraceEnabled()) {
- LOG.trace("Error for node {} : ", deviceContext.getDeviceInfo().getLOGValue(), e);
- }
- }
- }
-}
-/**
+/*
* Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
import org.opendaylight.openflowplugin.api.openflow.statistics.compatibility.Delegator;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
-import org.opendaylight.openflowplugin.impl.services.FlowCapableTransactionServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.NodeConfigServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.PacketProcessingServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalEchoServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalExperimenterMessageServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalExperimenterMpMessageServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalFlatBatchServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalFlowServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalFlowsBatchServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalGroupServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalGroupsBatchServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalMeterServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalMetersBatchServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalPortServiceImpl;
-import org.opendaylight.openflowplugin.impl.services.SalTableServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.FlowCapableTransactionServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.NodeConfigServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.PacketProcessingServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalEchoServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalExperimenterMessageServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalExperimenterMpMessageServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalFlowServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalFlowsBatchServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalGroupServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalGroupsBatchServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalMeterServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalMetersBatchServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalPortServiceImpl;
+import org.opendaylight.openflowplugin.impl.services.sal.SalTableServiceImpl;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightFlowStatisticsServiceImpl;
import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightFlowTableStatisticsServiceImpl;
import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightGroupStatisticsServiceImpl;
import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightPortStatisticsServiceImpl;
import org.opendaylight.openflowplugin.impl.statistics.services.OpendaylightQueueStatisticsServiceImpl;
import org.opendaylight.openflowplugin.impl.statistics.services.compatibility.OpendaylightFlowStatisticsServiceDelegateImpl;
-import org.opendaylight.openflowplugin.impl.statistics.services.direct.FlowDirectStatisticsService;
-import org.opendaylight.openflowplugin.impl.statistics.services.direct.GroupDirectStatisticsService;
-import org.opendaylight.openflowplugin.impl.statistics.services.direct.MeterDirectStatisticsService;
-import org.opendaylight.openflowplugin.impl.statistics.services.direct.NodeConnectorDirectStatisticsService;
import org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceImpl;
-import org.opendaylight.openflowplugin.impl.statistics.services.direct.OpendaylightDirectStatisticsServiceProvider;
-import org.opendaylight.openflowplugin.impl.statistics.services.direct.QueueDirectStatisticsService;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer.MultiLayerDirectStatisticsProviderInitializer;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.singlelayer.SingleLayerDirectStatisticsProviderInitializer;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.OpendaylightDirectStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SalEchoService;
* Method registers all OF services for role {@link OfpRole#BECOMEMASTER}
* @param rpcContext - registration processing is implemented in {@link org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext}
* @param deviceContext - every service needs {@link org.opendaylight.openflowplugin.api.openflow.device.DeviceContext} as input parameter
- * @param convertorExecutor
+ * @param convertorExecutor convertor executor
*/
public static void registerServices(@CheckForNull final RpcContext rpcContext,
@CheckForNull final DeviceContext deviceContext,
Preconditions.checkArgument(rpcContext != null);
Preconditions.checkArgument(deviceContext != null);
+ // TODO: Use multipart writer provider from device context
+ final MultipartWriterProvider multipartWriterProvider = MultipartWriterProviderFactory
+ .createDefaultProvider(deviceContext);
+
// create service instances
final SalFlowServiceImpl salFlowService = new SalFlowServiceImpl(rpcContext, deviceContext, convertorExecutor);
final FlowCapableTransactionServiceImpl flowCapableTransactionService = new FlowCapableTransactionServiceImpl(rpcContext, deviceContext);
rpcContext.registerRpcServiceImplementation(FlowCapableTransactionService.class, flowCapableTransactionService);
rpcContext.registerRpcServiceImplementation(SalMeterService.class, salMeterService);
rpcContext.registerRpcServiceImplementation(SalGroupService.class, salGroupService);
- rpcContext.registerRpcServiceImplementation(SalTableService.class, new SalTableServiceImpl(rpcContext, deviceContext, convertorExecutor));
+ rpcContext.registerRpcServiceImplementation(SalTableService.class, new SalTableServiceImpl(rpcContext, deviceContext, convertorExecutor, multipartWriterProvider));
rpcContext.registerRpcServiceImplementation(SalPortService.class, new SalPortServiceImpl(rpcContext, deviceContext, convertorExecutor));
rpcContext.registerRpcServiceImplementation(PacketProcessingService.class, new PacketProcessingServiceImpl(rpcContext, deviceContext, convertorExecutor));
rpcContext.registerRpcServiceImplementation(NodeConfigService.class, new NodeConfigServiceImpl(rpcContext, deviceContext));
rpcContext.registerRpcServiceImplementation(OpendaylightFlowStatisticsService.class, OpendaylightFlowStatisticsServiceImpl.createWithOook(rpcContext, deviceContext, convertorExecutor));
// register direct statistics gathering services
- final OpendaylightDirectStatisticsServiceProvider statisticsProvider = new OpendaylightDirectStatisticsServiceProvider();
- statisticsProvider.register(FlowDirectStatisticsService.class, new FlowDirectStatisticsService(rpcContext, deviceContext, convertorExecutor));
- statisticsProvider.register(GroupDirectStatisticsService.class, new GroupDirectStatisticsService(rpcContext, deviceContext, convertorExecutor));
- statisticsProvider.register(MeterDirectStatisticsService.class, new MeterDirectStatisticsService(rpcContext, deviceContext, convertorExecutor));
- statisticsProvider.register(NodeConnectorDirectStatisticsService.class, new NodeConnectorDirectStatisticsService(rpcContext, deviceContext, convertorExecutor));
- statisticsProvider.register(QueueDirectStatisticsService.class, new QueueDirectStatisticsService(rpcContext, deviceContext, convertorExecutor));
- rpcContext.registerRpcServiceImplementation(OpendaylightDirectStatisticsService.class, new OpendaylightDirectStatisticsServiceImpl(statisticsProvider));
+ rpcContext.registerRpcServiceImplementation(OpendaylightDirectStatisticsService.class,
+ new OpendaylightDirectStatisticsServiceImpl(deviceContext.canUseSingleLayerSerialization()
+ ? SingleLayerDirectStatisticsProviderInitializer
+ .createProvider(rpcContext, deviceContext, convertorExecutor, multipartWriterProvider)
+ : MultiLayerDirectStatisticsProviderInitializer
+ .createProvider(rpcContext, deviceContext, convertorExecutor, multipartWriterProvider)));
// register flat batch services
rpcContext.registerRpcServiceImplementation(SalFlatBatchService.class, new SalFlatBatchServiceImpl(
/**
* Support deprecated statistic related services for backward compatibility. The only exception from deprecation is
* the aggregated flow statistic with match criteria input.
- * @param rpcContext
+ * @param rpcContext
* @param deviceContext
* @param notificationPublishService
* @param convertorExecutor
+++ /dev/null
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.common;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortStateV10;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPort;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * openflowplugin-impl
- * org.opendaylight.openflowplugin.impl.common
- *
- * Test class for testing {@link org.opendaylight.openflowplugin.impl.common.NodeConnectorTranslatorUtil}
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Mar 31, 2015
- */
-public class NodeConnectorTranslatorUtilTest {
-
- private static final Logger LOG = LoggerFactory.getLogger(NodeConnectorTranslatorUtilTest.class);
-
- private static final String MAC_ADDRESS = "00:01:02:03:04:05";
- private static final String NAME = "PortTranslatorTest";
- private final Boolean[] pfBls = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
- private final boolean[] pfV10Bls = {false, false, false, false, false, false, false, false, false, false, false, false};
- private final boolean[] portCfgBools = {false, false, false, false};
- private final boolean[] portCfgV10bools = {false, false, false, false, false, false, false};
- private final boolean[] portStateBools = {false, false, false, false};
- private final Long currentSpeed = Long.decode("4294967295");
- private static final Long maxSpeed = Long.decode("4294967295");
-
- /**
- * Test method for {@link NodeConnectorTranslatorUtil#translateNodeConnectorFromFeaturesReply(FeaturesReply)}.
- */
- @Test
- public void testTranslateNodeConnectorFromFeaturesReply(){
- final FeaturesReply reply = mock(FeaturesReply.class);
- final BigInteger dataPathId = BigInteger.valueOf(25L);
- final List<PhyPort> listPorts = Arrays.asList(mockPhyPortPort());
- when(reply.getPhyPort()).thenReturn(listPorts);
- when(reply.getDatapathId()).thenReturn(dataPathId);
- when(reply.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
- final List<NodeConnector> nodeConnector = NodeConnectorTranslatorUtil.translateNodeConnectorFromFeaturesReply(reply);
- Assert.assertNotNull(nodeConnector);
- Assert.assertEquals(1, nodeConnector.size());
- }
-
- /**
- * Test method for {@link NodeConnectorTranslatorUtil#translateNodeConnectorFromFeaturesReply(FeaturesReply)}.
- * {@link IllegalArgumentException}
- */
- @Test(expected=IllegalArgumentException.class)
- public void testTranslateNodeConnectorFromFeaturesReplyNullPorts(){
- final FeaturesReply reply = mock(FeaturesReply.class);
- when(reply.getPhyPort()).thenReturn(null);
- NodeConnectorTranslatorUtil.translateNodeConnectorFromFeaturesReply(reply);
- }
-
- /**
- * Test method for {@link NodeConnectorTranslatorUtil#translateNodeConnectorFromFeaturesReply(FeaturesReply)}.
- * {@link IllegalArgumentException}
- */
- @Test(expected=IllegalArgumentException.class)
- public void testTranslateNodeConnectorFromFeaturesReplyNullReplay(){
- NodeConnectorTranslatorUtil.translateNodeConnectorFromFeaturesReply(null);
- }
-
- /**
- * Test method for {@link NodeConnectorTranslatorUtil#translateFlowCapableNodeFromPhyPort(PhyPort, short)}.
- */
- @Test
- public void testTranslateFlowCapableNodeFromPhyPortOF10(){
- final PhyPort port = mockPhyPortPort();
- final FlowCapableNodeConnector flowCapableNodeConnector = NodeConnectorTranslatorUtil
- .translateFlowCapableNodeFromPhyPort(port, OFConstants.OFP_VERSION_1_0);
- Assert.assertNotNull(flowCapableNodeConnector);
- Assert.assertEquals(port.getName(), flowCapableNodeConnector.getName());
- Assert.assertEquals(port.getPortNo(), flowCapableNodeConnector.getPortNumber().getUint32());
- Assert.assertEquals(port.getHwAddr().getValue(), flowCapableNodeConnector.getHardwareAddress().getValue());
- Assert.assertEquals(port.getCurrSpeed(), flowCapableNodeConnector.getCurrentSpeed());
- Assert.assertEquals(port.getMaxSpeed(), flowCapableNodeConnector.getMaximumSpeed());
- assertEqualsStateV10(port.getStateV10(), flowCapableNodeConnector.getState());
- assertEqualsPortFeaturesV10(port.getAdvertisedFeaturesV10(), flowCapableNodeConnector.getAdvertisedFeatures());
- assertEqualsPortFeaturesV10(port.getCurrentFeaturesV10(), flowCapableNodeConnector.getCurrentFeature());
- assertEqualsPortFeaturesV10(port.getPeerFeaturesV10(), flowCapableNodeConnector.getPeerFeatures());
- assertEqualsPortFeaturesV10(port.getSupportedFeaturesV10(), flowCapableNodeConnector.getSupported());
-
- }
-
- /**
- * Test method for {@link NodeConnectorTranslatorUtil#translateFlowCapableNodeFromPhyPort(PhyPort, short)}.
- */
- @Test
- public void testTranslateFlowCapableNodeFromPhyPortOF13(){
- final PhyPort port = mockPhyPortPort();
- final FlowCapableNodeConnector flowCapableNodeConnector = NodeConnectorTranslatorUtil
- .translateFlowCapableNodeFromPhyPort(port, OFConstants.OFP_VERSION_1_3);
- Assert.assertNotNull(flowCapableNodeConnector);
- Assert.assertEquals(port.getName(), flowCapableNodeConnector.getName());
- Assert.assertEquals(port.getPortNo(), flowCapableNodeConnector.getPortNumber().getUint32());
- Assert.assertEquals(port.getHwAddr().getValue(), flowCapableNodeConnector.getHardwareAddress().getValue());
- Assert.assertEquals(port.getCurrSpeed(), flowCapableNodeConnector.getCurrentSpeed());
- Assert.assertEquals(port.getMaxSpeed(), flowCapableNodeConnector.getMaximumSpeed());
- assertEqualsState(port.getState(), flowCapableNodeConnector.getState());
- assertEqualsPortFeatures(port.getAdvertisedFeatures(), flowCapableNodeConnector.getAdvertisedFeatures());
- assertEqualsPortFeatures(port.getCurrentFeatures(), flowCapableNodeConnector.getCurrentFeature());
- assertEqualsPortFeatures(port.getPeerFeatures(), flowCapableNodeConnector.getPeerFeatures());
- assertEqualsPortFeatures(port.getSupportedFeatures(), flowCapableNodeConnector.getSupported());
- }
-
- /**
- * Here unsupported version is used
- * Test method for {@link NodeConnectorTranslatorUtil#translateFlowCapableNodeFromPhyPort(PhyPort, short)}.
- */
- @Test
- public void testTranslateFlowCapableNodeFromPhyPortOF12() {
- final PhyPort port = mockPhyPortPort();
- try {
- final FlowCapableNodeConnector flowCapableNodeConnector = NodeConnectorTranslatorUtil
- .translateFlowCapableNodeFromPhyPort(port, (short) 0x03);
- Assert.fail("port of version 0x03 (OF-1.2) should not be translated");
- } catch (Exception e) {
- LOG.debug("expected exception: {}", e.getMessage());
- Assert.assertTrue(e instanceof IllegalArgumentException);
- }
-
- }
-
- /**
- * Test method for {@link NodeConnectorTranslatorUtil#makeNodeConnectorId(BigInteger, String, long)}.
- */
- @Test
- public void testMakeNodeConnectorId(){
- final BigInteger dataPathId = BigInteger.valueOf(25L);
- final String logicalName = "testPort";
- final long portNo = 45L;
- final NodeConnectorId nodeConnectorId = NodeConnectorTranslatorUtil.makeNodeConnectorId(dataPathId, logicalName, portNo);
- Assert.assertNotNull(nodeConnectorId);
- Assert.assertNotNull(nodeConnectorId.getValue());
- Assert.assertTrue(nodeConnectorId.getValue().contains(logicalName));
- Assert.assertTrue(nodeConnectorId.getValue().contains(dataPathId.toString()));
- Assert.assertFalse(nodeConnectorId.getValue().contains(":" + portNo));
- }
-
- /**
- * Test method for {@link NodeConnectorTranslatorUtil#makeNodeConnectorId(BigInteger, String, long)}.
- */
- @Test
- public void testMakeNodeConnectorIdNullLogicalName(){
- final BigInteger dataPathId = BigInteger.valueOf(25L);
- final long portNo = 45L;
- final NodeConnectorId nodeConnectorId = NodeConnectorTranslatorUtil.makeNodeConnectorId(dataPathId, null, portNo);
- Assert.assertNotNull(nodeConnectorId);
- Assert.assertNotNull(nodeConnectorId.getValue());
- Assert.assertTrue(nodeConnectorId.getValue().contains(dataPathId.toString()));
- Assert.assertTrue(nodeConnectorId.getValue().contains(":" + portNo));
- }
-
- /**
- * Test method for {@link NodeConnectorTranslatorUtil#makeNodeConnectorId(BigInteger, String, long)}.
- * expect {@link IllegalArgumentException}
- */
- @Test(expected=IllegalArgumentException.class)
- public void testMakeNodeConnectorIdNullDataPath(){
- final long portNo = 45L;
- NodeConnectorTranslatorUtil.makeNodeConnectorId(null, null, portNo);
- }
-
- private PhyPort mockPhyPortPort() {
- final PhyPort phyport = mock(PhyPort.class);
- when(phyport.getAdvertisedFeatures()).thenReturn(getPortFeatures());
- when(phyport.getAdvertisedFeaturesV10()).thenReturn(getPortFeaturesV10());
- when(phyport.getConfig()).thenReturn(getPortConfig());
- when(phyport.getConfigV10()).thenReturn(getPortConfigV10());
- when(phyport.getCurrentFeatures()).thenReturn(getPortFeatures());
- when(phyport.getCurrentFeaturesV10()).thenReturn(getPortFeaturesV10());
- when(phyport.getCurrSpeed()).thenReturn(currentSpeed);
- when(phyport.getHwAddr()).thenReturn(getMacAddress());
- when(phyport.getName()).thenReturn(NAME);
- when(phyport.getMaxSpeed()).thenReturn(maxSpeed);
- when(phyport.getPeerFeatures()).thenReturn(getPortFeatures());
- when(phyport.getPeerFeaturesV10()).thenReturn(getPortFeaturesV10());
- when(phyport.getPortNo()).thenReturn(Long.MAX_VALUE);
- when(phyport.getState()).thenReturn(getPortState());
- when(phyport.getStateV10()).thenReturn(getPortStateV10());
- when(phyport.getSupportedFeatures()).thenReturn(getPortFeatures());
- when(phyport.getSupportedFeaturesV10()).thenReturn(getPortFeaturesV10());
- return phyport;
- }
-
- private static PortStateV10 getPortStateV10() {
- final PortStateV10 portState = new PortStateV10(Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE, Boolean.TRUE);
- return portState;
- }
-
- private PortState getPortState() {
- final PortState portState = new PortState(portStateBools[0], portStateBools[1], portStateBools[2]);
- return portState;
- }
-
- private PortFeatures getPortFeatures() {
- return new PortFeatures(pfBls[0], pfBls[1], pfBls[2], pfBls[3], pfBls[4], pfBls[5], pfBls[6], pfBls[7], pfBls[8],
- pfBls[9], pfBls[10], pfBls[11], pfBls[12], pfBls[13], pfBls[14], pfBls[15]);
- }
-
- private PortFeaturesV10 getPortFeaturesV10() {
- return new PortFeaturesV10(pfV10Bls[0], pfV10Bls[1], pfV10Bls[2], pfV10Bls[3], pfV10Bls[4], pfV10Bls[5], pfV10Bls[6],
- pfV10Bls[7], pfV10Bls[8], pfV10Bls[9], pfV10Bls[10], pfV10Bls[11]);
- }
-
- private static MacAddress getMacAddress() {
- return new MacAddress(MAC_ADDRESS);
- }
-
- private PortConfigV10 getPortConfigV10() {
- return new PortConfigV10(portCfgV10bools[0], portCfgV10bools[1], portCfgV10bools[2], portCfgV10bools[3], portCfgV10bools[4], portCfgV10bools[5], portCfgV10bools[6]);
- }
-
- private PortConfig getPortConfig() {
- return new PortConfig(portCfgBools[0], portCfgBools[1], portCfgBools[2], portCfgBools[3]);
- }
-
- private static void assertEqualsStateV10(final PortStateV10 psV10, final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState state) {
- assertEquals(psV10.isBlocked(), state.isBlocked());
- assertEquals(psV10.isLinkDown(), state.isLinkDown());
- assertEquals(psV10.isLive(), state.isLive());
- }
-
- private static void assertEqualsState(final PortState ps, final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortState state) {
- assertEquals(ps.isBlocked(), state.isBlocked());
- assertEquals(ps.isLinkDown(), state.isLinkDown());
- assertEquals(ps.isLive(), state.isLive());
- }
-
- private static void assertEqualsPortFeaturesV10(final PortFeaturesV10 apfV10, final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures npf) {
- assertEquals(apfV10.is_100mbFd(), npf.isHundredMbFd());
- assertEquals(apfV10.is_100mbHd(), npf.isHundredMbHd());
-
- assertEquals(apfV10.is_10gbFd(), npf.isTenGbFd());
- assertEquals(apfV10.is_10mbFd(), npf.isTenMbFd());
- assertEquals(apfV10.is_10mbHd(), npf.isTenMbHd());
-
- assertEquals(apfV10.is_1gbFd(), npf.isOneGbFd());
- assertEquals(apfV10.is_1gbHd(), npf.isOneGbHd());
-
- assertEquals(apfV10.isAutoneg(), npf.isAutoeng());
- assertEquals(apfV10.isCopper(), npf.isCopper());
- assertEquals(apfV10.isFiber(), npf.isFiber());
- assertEquals(apfV10.isPause(), npf.isPause());
- assertEquals(apfV10.isPauseAsym(), npf.isPauseAsym());
- }
-
- private static void assertEqualsPortFeatures(final PortFeatures apf, final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures npf) {
- assertEquals(apf.is_100gbFd(), npf.isHundredGbFd());
- assertEquals(apf.is_100mbFd(), npf.isHundredMbFd());
- assertEquals(apf.is_100mbHd(), npf.isHundredMbHd());
-
- assertEquals(apf.is_10gbFd(), npf.isTenGbFd());
- assertEquals(apf.is_10mbFd(), npf.isTenMbFd());
- assertEquals(apf.is_10mbHd(), npf.isTenMbHd());
-
- assertEquals(apf.is_1gbFd(), npf.isOneGbFd());
- assertEquals(apf.is_1gbHd(), npf.isOneGbHd());
- assertEquals(apf.is_1tbFd(), npf.isOneTbFd());
-
- assertEquals(apf.is_40gbFd(), npf.isFortyGbFd());
-
- assertEquals(apf.isAutoneg(), npf.isAutoeng());
- assertEquals(apf.isCopper(), npf.isCopper());
- assertEquals(apf.isFiber(), npf.isFiber());
- assertEquals(apf.isOther(), npf.isOther());
- assertEquals(apf.isPause(), npf.isPause());
- assertEquals(apf.isPauseAsym(), npf.isPauseAsym());
- }
-
- static InstanceIdentifier<NodeConnector> createNodeConnectorId(String nodeKey, String nodeConnectorKey) {
- return InstanceIdentifier.builder(Nodes.class)
- .child(Node.class, new NodeKey(new NodeId(nodeKey)))
- .child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId(nodeConnectorKey)))
- .build();
- }
-
- @Test
- public void testDummy() {
- InstanceIdentifier<NodeConnector> id = createNodeConnectorId("openflow:1", "openflow:1:1");
- InstanceIdentifier<Node> nodeId = id.firstIdentifierOf(Node.class);
- System.out.println(nodeId);
- }
-}
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProviderFactory;
import org.opendaylight.openflowplugin.impl.registry.flow.FlowDescriptorFactory;
import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil;
translatorLibrary,
deviceManager,
convertorExecutor,
- false, timer, deviceManager, false);
+ false, timer, deviceManager, false,
+ DeviceInitializerProviderFactory.createDefaultProvider());
deviceContextSpy = Mockito.spy(deviceContext);
xid = new Xid(atomicLong.incrementAndGet());
}
- @Test(expected = NullPointerException.class)
- public void testDeviceContextImplConstructorNullDataBroker() throws Exception {
- new DeviceContextImpl(connectionContext, null, null, translatorLibrary, deviceManager, convertorExecutor,false, timer, deviceManager, false).close();
- }
-
- @Test(expected = NullPointerException.class)
- public void testDeviceContextImplConstructorNullTimer() throws Exception {
- new DeviceContextImpl(null, dataBroker, null, translatorLibrary, deviceManager,convertorExecutor,false, timer, deviceManager, false).close();
- }
-
@Test
public void testGetReadTransaction() {
final ReadTransaction readTx = deviceContext.getReadTransaction();
@Test
public void testProcessReply2() {
- final MultipartReply mockedMultipartReply = mock(MultipartReply.class);
final Xid dummyXid = new Xid(DUMMY_XID);
- deviceContext.processReply(dummyXid, Lists.newArrayList(mockedMultipartReply));
+
+ final Error mockedError = mock(Error.class);
+ deviceContext.processReply(dummyXid, Lists.newArrayList(mockedError));
verify(messageSpy).spyMessage(any(Class.class), eq(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_FAILURE));
+
+ final MultipartReply mockedMultipartReply = mock(MultipartReply.class);
+ deviceContext.processReply(dummyXid, Lists.newArrayList(mockedMultipartReply));
+ verify(messageSpy).spyMessage(any(Class.class), eq(MessageSpy.STATISTIC_GROUP.FROM_SWITCH_PUBLISHED_SUCCESS));
}
@Test
import org.opendaylight.openflowplugin.api.openflow.lifecycle.LifecycleService;
import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency;
+import org.opendaylight.openflowplugin.impl.device.initialization.DeviceInitializerProviderFactory;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
when(mockedWriteTransaction.submit()).thenReturn(mockedFuture);
final DeviceManagerImpl deviceManager = new DeviceManagerImpl(
- mockedDataBroker,
- TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA,
- false,
- barrierIntervalNanos,
- barrierCountLimit,
- messageIntelligenceAgency,
- true,
- clusterSingletonServiceProvider,
- null,
- new HashedWheelTimer(),
- convertorExecutor,
- false,
- false);
+ mockedDataBroker,
+ TEST_VALUE_GLOBAL_NOTIFICATION_QUOTA,
+ false,
+ barrierIntervalNanos,
+ barrierCountLimit,
+ messageIntelligenceAgency,
+ true,
+ clusterSingletonServiceProvider,
+ null,
+ new HashedWheelTimer(),
+ convertorExecutor,
+ false,
+ false,
+ DeviceInitializerProviderFactory.createDefaultProvider());
deviceManager.setDeviceInitializationPhaseHandler(deviceInitPhaseHandler);
deviceManager.setDeviceTerminationPhaseHandler(deviceTerminationPhaseHandler);
@RunWith(MockitoJUnitRunner.class)
public class MultiMsgCollectorImplTest {
- private MultiMsgCollectorImpl collector;
+ private MultiMsgCollectorImpl<MultipartReply> collector;
private Runnable cleanUpCheck;
@Mock
@Before
public void setUp() {
- collector = new MultiMsgCollectorImpl(deviceProcessor, requestContext);
+ collector = new MultiMsgCollectorImpl<>(deviceProcessor, requestContext);
cleanUpCheck = Runnables.doNothing();
Mockito.when(requestContext.getXid()).thenReturn(new Xid(xid));
}
*/
@Test
public void testAddMultipartMsgOne() {
- collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build());
+ collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build(), false, null);
Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture());
Assert.assertEquals(xid, xidCaptor.getValue().getValue());
*/
@Test
public void testAddMultipartMsgTwo() {
- collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build());
- collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build());
+ collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build(), true, null);
+ collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build(), false, null);
Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture());
Assert.assertEquals(xid, xidCaptor.getValue().getValue());
public void testAddMultipartMsgNotExpectedXid() {
final Long dif_xid = 5L;
final MultipartReplyMessage mrMsg = MsgGeneratorTestUtils.makeMultipartDescReply(dif_xid, hwTestValue, true).build();
- collector.addMultipartMsg(mrMsg);
+ collector.addMultipartMsg(mrMsg, true, null);
}
/**
*/
@Test
public void testAddMultipartMsgWrongType1() {
- collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build());
+ collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build(), true, null);
collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false)
- .setType(MultipartType.OFPMPPORTDESC).build());
+ .setType(MultipartType.OFPMPPORTDESC).build(), false, null);
Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture());
Assert.assertEquals(xid, xidCaptor.getValue().getValue());
*/
@Test
public void testAddMultipartMsgWrongType2() {
- collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build());
+ collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build(), true, null);
collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true)
- .setType(MultipartType.OFPMPPORTDESC).build());
- collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build());
+ .setType(MultipartType.OFPMPPORTDESC).build(), true, null);
+ collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build(), false, null);
Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture());
Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture());
*/
@Test
public void testAddMultipartMsgWrongType3() {
- collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build());
+ collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true).build(), true, null);
collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, true)
- .setType(MultipartType.OFPMPPORTDESC).build());
- collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build());
+ .setType(MultipartType.OFPMPPORTDESC).build(), true, null);
+ collector.addMultipartMsg(MsgGeneratorTestUtils.makeMultipartDescReply(xid, hwTestValue, false).build(), false, null);
Mockito.verify(deviceProcessor).processReply(xidCaptor.capture(), mmCaptor.capture());
Assert.assertEquals(xid, xidCaptor.getValue().getValue());
factory.setRegistry(registry);
provider = new DeserializerExtensionProviderImpl(registry, factory);
DeserializerInjector.injectDeserializers(provider);
+ MessageDeserializerInjector.injectDeserializers(provider);
init();
}
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.stubbing.OngoingStubbing;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerMultipartRequestCallback;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
import org.opendaylight.yangtools.yang.common.RpcResult;
/**
- * Test for {@link MultipartRequestCallback}.
+ * Test for {@link org.opendaylight.openflowplugin.impl.services.AbstractMultipartRequestCallback}.
*/
@RunWith(MockitoJUnitRunner.class)
public class MultipartRequestCallbackTest {
@Mock
private MessageSpy spy;
@Mock
- private MultiMsgCollector multiMsgCollector;
+ private MultiMsgCollector<MultipartReply> multiMsgCollector;
@Captor
private ArgumentCaptor<RpcResult<List<MultipartReply>>> rpcResultCapt;
- private MultipartRequestCallback multipartRequestCallback;
+ private AbstractMultipartRequestCallback<MultipartReply> multipartRequestCallback;
@Before
public void setUp() throws Exception {
Mockito.doNothing().when(requestContext).setResult(rpcResultCapt.capture());
Mockito.when(deviceContext.getMessageSpy()).thenReturn(spy);
- Mockito.when(deviceContext.getMultiMsgCollector(Matchers.<RequestContext>any())).thenReturn(multiMsgCollector);
- multipartRequestCallback = new MultipartRequestCallback(requestContext, MultipartRequestInput.class, deviceContext);
+
+ final OngoingStubbing<MultiMsgCollector<MultipartReply>> when =
+ Mockito.when(deviceContext.getMultiMsgCollector(Matchers.any()));
+ when.thenReturn(multiMsgCollector);
+ multipartRequestCallback = new MultiLayerMultipartRequestCallback<>(requestContext, MultipartRequestInput.class, deviceContext, null);
}
/**
public void testOnSuccess3() throws Exception {
final MultipartReplyMessage replyMessage = new MultipartReplyMessageBuilder().build();
multipartRequestCallback.onSuccess(replyMessage);
- Mockito.verify(multiMsgCollector).addMultipartMsg(Matchers.eq(replyMessage), Matchers.<EventIdentifier>any());
+ Mockito.verify(multiMsgCollector).addMultipartMsg(Matchers.eq(replyMessage), Matchers.eq(false), Matchers.any());
}
-}
\ No newline at end of file
+}
package org.opendaylight.openflowplugin.impl.services;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerFlowMultipartRequestOnTheFlyCallback;
import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
private AbstractRequestContext<List<MultipartReply>> dummyRequestContext;
private final EventIdentifier dummyEventIdentifier = new EventIdentifier(DUMMY_EVENT_NAME, DUMMY_DEVICE_ID);
- private MultipartRequestOnTheFlyCallback multipartRequestOnTheFlyCallback;
+ private AbstractMultipartRequestOnTheFlyCallback<MultipartReply> multipartRequestOnTheFlyCallback;
private final short tableId = 0;
@Before
};
final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
- multipartRequestOnTheFlyCallback = new MultipartRequestOnTheFlyCallback(dummyRequestContext, String.class,
- mockedDeviceContext.getMessageSpy(),dummyEventIdentifier, mockedDeviceInfo,
- mockedDeviceContext.getDeviceFlowRegistry(), mockedDeviceContext, convertorManager);
+ multipartRequestOnTheFlyCallback = new MultiLayerFlowMultipartRequestOnTheFlyCallback<>(
+ dummyRequestContext,
+ String.class,
+ mockedDeviceContext,
+ dummyEventIdentifier,
+ MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext),
+ convertorManager);
}
multipartRequestOnTheFlyCallback.onSuccess(mpReplyMessage.build());
final RpcResult<List<MultipartReply>> actualResult = dummyRequestContext.getFuture().get();
- assertNotNull(actualResult.getErrors());
- assertTrue(actualResult.getErrors().isEmpty());
- assertNotNull(actualResult.getResult());
- assertTrue(actualResult.getResult().isEmpty());
+ // Nothing else than flow is supported by on the fly callback
+ assertNotNull(actualResult.getErrors());
+ assertFalse(actualResult.getErrors().isEmpty());
Mockito.verify(mockedFlowRegistry, Mockito.never()).storeIfNecessary(Matchers.any());
Mockito.verify(mockedDeviceContext, Mockito.never()).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
Matchers.<InstanceIdentifier>any(), Matchers.<DataObject>any());
/*
- * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.impl.services.multilayer.MultiLayerExperimenterMultipartService;
+import org.opendaylight.openflowplugin.impl.services.sal.SalExperimenterMpMessageServiceImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.mp.message.service.rev151020.SendExperimenterMpRequestInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
.setNode(new NodeRef(mockedDeviceInfo.getNodeInstanceIdentifier()))
.build();
- final OfHeader ofHeader = salExperimenterMpMessageService.buildRequest(new Xid(DUMMY_ID), data);
+ final OfHeader ofHeader = new MultiLayerExperimenterMultipartService(mockedDeviceContext, mockedDeviceContext, mockedExtensionConverterProvider)
+ .buildRequest(new Xid(DUMMY_ID), data);
verify(mockedExtensionConverter).convert(data.getExperimenterMessageOfChoice());
assertEquals(DUMMY_ID, (long) ofHeader.getXid());
assertEquals(mockedDeviceInfo.getVersion(), (short) ofHeader.getVersion());
return DummyExperimenter.class;
}
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
+import org.opendaylight.openflowplugin.impl.services.sal.FlowCapableTransactionServiceImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
/**
- * Test for {@link FlowCapableTransactionServiceImpl}.
+ * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.FlowCapableTransactionServiceImpl}.
*/
public class FlowCapableTransactionServiceImplTest extends ServiceMocking {
return new SendBarrierInputBuilder()
.setNode(new NodeRef(mockedDeviceInfo.getNodeInstanceIdentifier())).build();
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
+import org.opendaylight.openflowplugin.impl.services.sal.NodeConfigServiceImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfigInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.module.config.rev141015.SetConfigInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFlag;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
-public class NodeConfigServiceImplTest extends ServiceMocking{
+public class NodeConfigServiceImplTest extends ServiceMocking {
private static final Long DUMMY_XID_VALUE = 150L;
private static final SwitchConfigFlag DUMMY_FLAG = SwitchConfigFlag.FRAGNORMAL;
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
/**
- * Test for {@link PacketProcessingServiceImpl}.
+ * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.PacketProcessingServiceImpl}.
*/
public class PacketProcessingServiceImplTest extends ServiceMocking {
.setEgress(new NodeConnectorRef(pathToNodeconnector));
return transmitPacketInputBld.build();
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.mockito.Mockito.verify;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mockito;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
+import org.opendaylight.openflowplugin.impl.services.sal.SalEchoServiceImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoOutput;
verify(mockedRequestContextStack).createRequestContext();
verify(mockedOutboundQueue).commitEntry(Matchers.eq(2121L), Matchers.<OfHeader>any(), Matchers.<FutureCallback<OfHeader>>any());
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenterInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenterInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yangtools.yang.binding.DataContainer;
/**
- * Test for {@link SalExperimenterMessageServiceImpl}.
+ * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalExperimenterMessageServiceImpl}.
*/
public class SalExperimenterMessageServiceImplTest extends ServiceMocking {
}
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.AsyncFunction;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
/**
- * Test for {@link SalFlatBatchServiceImpl}.
+ * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlatBatchServiceImpl}.
*/
@RunWith(MockitoJUnitRunner.class)
public class SalFlatBatchServiceImplTest {
Mockito.verify(salFlowsBatchService, Mockito.times(2)).addFlowsBatch(addFlowsBatchInputCpt.capture());
Assert.assertEquals(2, addFlowsBatchInputCpt.getValue().getBatchAddFlows().size());
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.mockito.Mockito.mock;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.impl.services.sal.SalFlowServiceImpl;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
when(mockedDeviceInfo.getVersion()).thenReturn(version);
if (OFConstants.OFP_VERSION_1_3 >= version) {
- when(mockedDeviceContext.isUseSingleLayerSerialization()).thenReturn(true);
+ when(mockedDeviceContext.canUseSingleLayerSerialization()).thenReturn(true);
}
final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.collect.Lists;
import java.util.List;
import org.slf4j.LoggerFactory;
/**
- * Test for {@link SalFlowsBatchServiceImpl}.
+ * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalFlowsBatchServiceImpl}.
*/
@RunWith(MockitoJUnitRunner.class)
public class SalFlowsBatchServiceImplTest {
inOrder.verify(transactionService).sendBarrier(Matchers.<SendBarrierInput>any());
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import org.mockito.Mock;
import org.opendaylight.openflowplugin.api.openflow.registry.group.DeviceGroupRegistry;
import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.collect.Lists;
import java.util.List;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowplugin.impl.services.sal.SalGroupsBatchServiceImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
/**
- * Test for {@link SalGroupsBatchServiceImpl}.
+ * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalGroupsBatchServiceImpl}.
*/
@RunWith(MockitoJUnitRunner.class)
public class SalGroupsBatchServiceImplTest {
.setUpdatedBatchedGroup(new UpdatedBatchedGroupBuilder(createEmptyBatchAddGroup(groupIdValue+1)).build())
.build();
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import org.mockito.Mock;
import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
import org.opendaylight.openflowplugin.api.openflow.rpc.listener.ItemLifecycleListener;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import com.google.common.collect.Lists;
import java.util.List;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowplugin.impl.services.sal.SalMetersBatchServiceImpl;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.FlowCapableTransactionService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.SendBarrierInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
/**
- * Test for {@link SalMetersBatchServiceImpl}.
+ * Test for {@link org.opendaylight.openflowplugin.impl.services.sal.SalMetersBatchServiceImpl}.
*/
@RunWith(MockitoJUnitRunner.class)
public class SalMetersBatchServiceImplTest {
.setUpdatedBatchedMeter(new UpdatedBatchedMeterBuilder(createEmptyBatchAddMeter(groupIdValue + 1)).build())
.build();
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.mockito.Mockito.verify;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
+import org.opendaylight.openflowplugin.impl.services.sal.SalPortServiceImpl;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
-/**
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.impl.services.sal.SalRoleServiceImpl;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.services;
+package org.opendaylight.openflowplugin.impl.services.sal;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
+import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
salTableService = new SalTableServiceImpl(mockedRequestContextStack, mockedDeviceContext,
- convertorManager);
+ convertorManager, MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext));
}
@Test
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
+import org.opendaylight.openflowplugin.impl.common.MultipartReplyTranslatorUtil;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.AggregateFlowStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionAware;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupStatisticsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowAndStatisticsMapList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupDescStatsReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupStatisticsReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.AggregateFlowStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.multipart.reply.group.desc.GroupDescBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStatsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStatsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsUpdate;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
-import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
-public class SinglePurposeMultipartReplyTranslatorTest {
+public class MultipartReplyTranslatorTest {
private static final BigInteger DUMMY_DATAPATH_ID = new BigInteger("21");
private static final Long DUMMY_XID = 1L;
- private SinglePurposeMultipartReplyTranslator singlePurposeMultipartReplyTranslator;
private static final BigInteger DUMMY_BYTE_COUNT = new BigInteger("31");
private static final BigInteger DUMMY_PACKET_COUNT = new BigInteger("41");
private static final Long DUMMY_FLOW_COUNT = 51L;
private static final Long DUMMY_REF_COUNT = 1234L;
private static final GroupTypes DUMMY_GROUPS_TYPE = GroupTypes.GroupAll;
private static final GroupType DUMMY_GROUP_TYPE = GroupType.OFPGTALL;
+ private static final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
@Before
public void setUp() {
- final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
- singlePurposeMultipartReplyTranslator = new SinglePurposeMultipartReplyTranslator(convertorManager);
}
@Test
MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyFlow(), MultipartType.OFPMPFLOW);
- List<DataObject> result = singlePurposeMultipartReplyTranslator.translate(
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(),
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(),
- multipartReplyMessage);
+ DataContainer result = MultipartReplyTranslatorUtil.translate(
+ multipartReplyMessage,
+ mockedDeviceContext.getDeviceInfo(),
+ convertorManager,
+ mockedDeviceContext.oook()).get();
- DataObject dataObject = validateOutput(result);
- assertTrue(dataObject instanceof FlowsStatisticsUpdate);
+ DataContainer dataObject = validateOutput(result);
+ assertTrue(dataObject instanceof FlowAndStatisticsMapList);
}
@Test
MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyAggregate(), MultipartType.OFPMPAGGREGATE);
- List<DataObject> result = singlePurposeMultipartReplyTranslator.translate(
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(),
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(),
- multipartReplyMessage);
+ DataContainer result = MultipartReplyTranslatorUtil.translate(
+ multipartReplyMessage,
+ mockedDeviceContext.getDeviceInfo(),
+ convertorManager,
+ mockedDeviceContext.oook()).get();
- DataObject dataObject = validateOutput(result);
- assertTrue(dataObject instanceof AggregateFlowStatisticsUpdate);
- AggregateFlowStatisticsUpdate message = (AggregateFlowStatisticsUpdate)dataObject;
+ DataContainer dataObject = validateOutput(result);
+ assertTrue(dataObject instanceof AggregateFlowStatistics);
+ AggregateFlowStatistics message = (AggregateFlowStatistics)dataObject;
assertEquals(DUMMY_BYTE_COUNT, message.getByteCount().getValue());
assertEquals(DUMMY_PACKET_COUNT, message.getPacketCount().getValue());
assertEquals(DUMMY_FLOW_COUNT, message.getFlowCount().getValue());
MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyPortStats(), MultipartType.OFPMPPORTSTATS);
- List<DataObject> result = singlePurposeMultipartReplyTranslator.translate(
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(),
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(),
- multipartReplyMessage);
+ DataContainer result = MultipartReplyTranslatorUtil.translate(
+ multipartReplyMessage,
+ mockedDeviceContext.getDeviceInfo(),
+ convertorManager,
+ mockedDeviceContext.oook()).get();
- DataObject dataObject = validateOutput(result);
- assertTrue(dataObject instanceof NodeConnectorStatisticsUpdate);
- NodeConnectorStatisticsUpdate nodeConnectorStatisticsUpdate = (NodeConnectorStatisticsUpdate)dataObject;
+ DataContainer dataObject = validateOutput(result);
+ assertTrue(dataObject instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsAndPortNumberMap);
+ org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsAndPortNumberMap nodeConnectorStatisticsUpdate = (org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.NodeConnectorStatisticsAndPortNumberMap)dataObject;
List<NodeConnectorStatisticsAndPortNumberMap> nodeConnectorStatisticsAndPortNumberMaps = nodeConnectorStatisticsUpdate.getNodeConnectorStatisticsAndPortNumberMap();
assertEquals(1, nodeConnectorStatisticsAndPortNumberMaps.size());
NodeConnectorStatisticsAndPortNumberMap nodeConnectorStatisticsAndPortNumberMap = nodeConnectorStatisticsAndPortNumberMaps.get(0);
MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyGroup(), MultipartType.OFPMPGROUP);
- List<DataObject> result = singlePurposeMultipartReplyTranslator.translate(
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(),
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(),
- multipartReplyMessage);
+ DataContainer result = MultipartReplyTranslatorUtil.translate(
+ multipartReplyMessage,
+ mockedDeviceContext.getDeviceInfo(),
+ convertorManager,
+ mockedDeviceContext.oook()).get();
- DataObject dataObject = validateOutput(result);
- assertTrue(dataObject instanceof GroupStatisticsUpdated);
- GroupStatisticsUpdated groupStatisticsUpdate = (GroupStatisticsUpdated)dataObject;
+ DataContainer dataObject = validateOutput(result);
+ assertTrue(dataObject instanceof GroupStatisticsReply);
+ GroupStatisticsReply groupStatisticsUpdate = (GroupStatisticsReply)dataObject;
List<org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats> groupStats = groupStatisticsUpdate.getGroupStats();
assertEquals(1, groupStats.size());
org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats groupStat = groupStats.get(0);
MultipartReplyMessage multipartReplyMessage = prepareMocks(mockedDeviceContext, prepareMultipartReplyGroupDesc(), MultipartType.OFPMPGROUPDESC);
- List<DataObject> result = singlePurposeMultipartReplyTranslator.translate(
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getDatapathId(),
- mockedDeviceContext.getPrimaryConnectionContext().getFeatures().getVersion(),
- multipartReplyMessage);
+ DataContainer result = MultipartReplyTranslatorUtil.translate(
+ multipartReplyMessage,
+ mockedDeviceContext.getDeviceInfo(),
+ convertorManager,
+ mockedDeviceContext.oook()).get();
- DataObject dataObject = validateOutput(result);
- assertTrue(dataObject instanceof GroupDescStatsUpdated);
- GroupDescStatsUpdated groupStatistics = (GroupDescStatsUpdated) dataObject;
+ DataContainer dataObject = validateOutput(result);
+ assertTrue(dataObject instanceof GroupDescStatsReply);
+ GroupDescStatsReply groupStatistics = (GroupDescStatsReply) dataObject;
List<GroupDescStats> groupDescStats = groupStatistics.getGroupDescStats();
assertEquals(1, groupDescStats.size());
GroupDescStats groupDescStat = groupDescStats.get(0);
when(mockedFeaturesReply.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
when(mockedFeaturesReply.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID);
+ DeviceInfo deviceInfo = mock(DeviceInfo.class);
+ when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
+ when(deviceInfo.getDatapathId()).thenReturn(DUMMY_DATAPATH_ID);
+ when(deviceInfo.getLOGValue()).thenReturn(DUMMY_DATAPATH_ID.toString());
+ when(mockedDeviceContext.getDeviceInfo()).thenReturn(deviceInfo);
+
when(mockedConnectionContext.getFeatures()).thenReturn(mockedFeaturesReply);
when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedConnectionContext);
}
- private DataObject validateOutput(List<DataObject> input) {
- assertEquals(input.size(), 1);
- DataObject dataObject = input.get(0);
- assertTrue(dataObject instanceof Node);
- assertEquals("openflow:" + DUMMY_DATAPATH_ID, ((Node) dataObject).getId().getValue());
- assertTrue(dataObject instanceof TransactionAware);
- assertEquals(new BigInteger(DUMMY_XID.toString()), ((TransactionAware) dataObject).getTransactionId().getValue());
+ private DataContainer validateOutput(DataContainer dataObject) {
return dataObject;
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
protected DeviceContext mockedDeviceContext;
protected DeviceState mockedDeviceState;
- StatisticsGatheringService mockedStatisticsGatheringService;
- StatisticsGatheringOnTheFlyService mockedStatisticsOnFlyGatheringService;
+ StatisticsGatheringService<MultipartReply> mockedStatisticsGatheringService;
+ StatisticsGatheringOnTheFlyService<MultipartReply> mockedStatisticsOnFlyGatheringService;
ConnectionContext mockedConnectionContext;
DeviceInfo mockedDeviceInfo;
StatisticsManager mockedStatisticsManager;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
- final StatisticsContextImpl statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, true, lifecycleService ,convertorManager, mockedStatisticsManager);
+ final StatisticsContextImpl<MultipartReply> statisticsContext = new StatisticsContextImpl<>(mockedDeviceInfo, true, lifecycleService ,convertorManager, mockedStatisticsManager,
+ MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext));
final ListenableFuture<RpcResult<List<MultipartReply>>> rpcResult = immediateFuture(RpcResultBuilder.success(Collections.<MultipartReply>emptyList()).build());
when(mockedStatisticsGatheringService.getStatisticsOfType(any(EventIdentifier.class), any(MultipartType
import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
private static final Logger LOG = LoggerFactory.getLogger(StatisticsContextImplTest.class);
private static final Long TEST_XID = 55L;
- private StatisticsContextImpl statisticsContext;
+ private StatisticsContextImpl<MultipartReply> statisticsContext;
private ConvertorManager convertorManager;
@Before
}
private void initStatisticsContext() {
- statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, true, lifecycleService, convertorManager, mockedStatisticsManager);
+ statisticsContext = new StatisticsContextImpl<>(mockedDeviceInfo, true, lifecycleService, convertorManager, mockedStatisticsManager,
+ MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext));
+
statisticsContext.setStatisticsGatheringService(mockedStatisticsGatheringService);
statisticsContext.setStatisticsGatheringOnTheFlyService(mockedStatisticsOnFlyGatheringService);
}
*/
@Test
public void testClose() throws Exception {
- final StatisticsContextImpl statisticsContext = new StatisticsContextImpl(mockedDeviceInfo, true, lifecycleService, convertorManager, mockedStatisticsManager);
+ final StatisticsContextImpl<MultipartReply> statisticsContext = new StatisticsContextImpl<>(mockedDeviceInfo, true, lifecycleService, convertorManager, mockedStatisticsManager,
+ MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext));
+
final RequestContext<Object> requestContext = statisticsContext.createRequestContext();
statisticsContext.close();
try {
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
-import org.opendaylight.openflowplugin.api.openflow.device.TxFacade;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowDescriptor;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.FlowRegistryKey;
import org.opendaylight.openflowplugin.api.openflow.registry.meter.DeviceMeterRegistry;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.StatisticsGatherer;
-import org.opendaylight.openflowplugin.impl.registry.flow.FlowRegistryKeyFactory;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
@Mock
private ConnectionContext connectionAdapter;
@Mock
- private StatisticsGatherer statisticsService;
+ private StatisticsGatherer<MultipartReply> statisticsService;
@Mock
private DeviceInfo deviceInfo;
- @Mock
- private TxFacade txFacade;
- private SinglePurposeMultipartReplyTranslator singlePurposeMultipartReplyTranslator;
+ private MultipartWriterProvider provider;
@Before
public void setUp() throws Exception {
- final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
- singlePurposeMultipartReplyTranslator = new SinglePurposeMultipartReplyTranslator(convertorManager);
when(deviceContext.getDeviceState()).thenReturn(deviceState);
when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
when(deviceContext.getDeviceFlowRegistry()).thenReturn(deviceFlowRegistry);
when(deviceContext.getDeviceMeterRegistry()).thenReturn(deviceMeterRegistry);
when(deviceFlowRegistry.retrieveIdForFlow(Matchers.any(FlowRegistryKey.class))).thenReturn(flowDescriptor);
when(deviceContext.getReadTransaction()).thenReturn(readTx);
- when(txFacade.getReadTransaction()).thenReturn(readTx);
+ when(deviceContext.getReadTransaction()).thenReturn(readTx);
when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionAdapter);
when(connectionAdapter.getNodeId()).thenReturn(DUMMY_NODE_ID);
when(connectionAdapter.getFeatures()).thenReturn(features);
when(features.getDatapathId()).thenReturn(BigInteger.ONE);
when(features.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
-
when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
when(deviceInfo.getDatapathId()).thenReturn(BigInteger.ONE);
when(deviceInfo.getNodeInstanceIdentifier()).thenReturn(dummyNodePath);
when(deviceInfo.getNodeId()).thenReturn(DUMMY_NODE_ID);
+ provider = MultipartWriterProviderFactory.createDefaultProvider(deviceContext);
}
@Test
final ArgumentCaptor<InstanceIdentifier> flowPath = ArgumentCaptor.forClass(InstanceIdentifier.class);
final ArgumentCaptor<Flow> flow = ArgumentCaptor.forClass(Flow.class);
- StatisticsGatheringUtils.writeFlowStatistics(prepareFlowStatisticsData(),
- deviceInfo, deviceContext.getDeviceFlowRegistry(), deviceContext);
+ provider.lookup(MultipartType.OFPMPFLOW).get().write(prepareFlowStatisticsData().iterator().next(), false);
Mockito.verify(deviceContext).writeToTransaction(
dataStoreType.capture(), flowPath.capture(), flow.capture());
.child(Group.class, new GroupKey(new org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId(groupIdValue)))
.augmentation(NodeGroupStatistics.class)
.child(GroupStatistics.class);
- verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
+ verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
Matchers.eq(groupPath), Matchers.any(GroupStatistics.class));
}
verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<?>> any());
verify(deviceGroupRegistry).removeMarked();
verify(deviceGroupRegistry).store(storedGroupId);
- verify(txFacade).writeToTransaction(
+ verify(deviceContext).writeToTransaction(
Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(groupPath), Matchers.any(Group.class));
}
.child(Meter.class, new MeterKey(new org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId(meterIdValue)))
.augmentation(NodeMeterStatistics.class)
.child(MeterStatistics.class);
- verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
+ verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL),
Matchers.eq(meterPath), Matchers.any(MeterStatistics.class));
}
.child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:" + DUMMY_NODE_ID_VALUE + ":11")))
.augmentation(FlowCapableNodeConnectorStatisticsData.class)
.child(FlowCapableNodeConnectorStatistics.class);
- verify(txFacade).writeToTransaction(
+ verify(deviceContext).writeToTransaction(
Matchers.eq(LogicalDatastoreType.OPERATIONAL),
Matchers.eq(portPath),
Matchers.any(FlowCapableNodeConnectorStatistics.class));
.child(Table.class, new TableKey((short) 0))
.augmentation(FlowTableStatisticsData.class)
.child(FlowTableStatistics.class);
- verify(txFacade).writeToTransaction(
+ verify(deviceContext).writeToTransaction(
Matchers.eq(LogicalDatastoreType.OPERATIONAL),
Matchers.eq(tablePath),
Matchers.any(FlowTableStatistics.class));
.child(NodeConnector.class, new NodeConnectorKey(new NodeConnectorId("openflow:" + DUMMY_NODE_ID_VALUE + ":11")))
.augmentation(FlowCapableNodeConnector.class)
.child(Queue.class, new QueueKey(new QueueId(queueIdValue)));
- verify(txFacade).writeToTransaction(
+ verify(deviceContext).writeToTransaction(
Matchers.eq(LogicalDatastoreType.OPERATIONAL),
Matchers.eq(queuePath),
Matchers.any(Queue.class));
verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<?>>any());
- final InOrder inOrder = Mockito.inOrder(txFacade);
- inOrder.verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(tablePath), Matchers.any(Table.class));
+ final InOrder inOrder = Mockito.inOrder(deviceContext);
+ inOrder.verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(tablePath), Matchers.any(Table.class));
}
@Test
.child(Meter.class, new MeterKey(meterId));
verify(deviceContext, Mockito.never()).addDeleteToTxChain(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.<InstanceIdentifier<?>>any());
verify(deviceMeterRegistry).store(meterId);
- verify(txFacade).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(meterPath), Matchers.any(Meter.class));
+ verify(deviceContext).writeToTransaction(Matchers.eq(LogicalDatastoreType.OPERATIONAL), Matchers.eq(meterPath), Matchers.any(Meter.class));
}
private void fireAndCheck(final MultipartType type, final List<MultipartReply> statsData) throws InterruptedException, ExecutionException, TimeoutException {
.thenReturn(Futures.immediateFuture(RpcResultBuilder.success(statsData).build()));
final ListenableFuture<Boolean> gatherStatisticsResult = StatisticsGatheringUtils.gatherStatistics(
- statisticsService,
- deviceInfo,
- type,
- txFacade,
- deviceContext,
- false,
- singlePurposeMultipartReplyTranslator);
- Assert.assertTrue(gatherStatisticsResult.get(1, TimeUnit.SECONDS).booleanValue());
- verify(txFacade).submitTransaction();
+ statisticsService,
+ deviceInfo,
+ type,
+ deviceContext,
+ deviceContext,
+ false,
+ ConvertorManagerFactory.createDefaultManager(),
+ provider);
+
+ Assert.assertTrue(gatherStatisticsResult.get(1, TimeUnit.SECONDS));
+ verify(deviceContext).submitTransaction();
}
private static MultipartReplyMessage assembleMPReplyMessage(final MultipartType type, final MultipartReplyBody mpReplyGroupCaseBld) {
final KeyedInstanceIdentifier<Table, TableKey> tablePath = deviceInfo.getNodeInstanceIdentifier()
.augmentation(FlowCapableNode.class).child(Table.class, new TableKey(tableId));
- StatisticsGatheringUtils.deleteAllKnownFlows(deviceInfo,
- deviceContext.getDeviceFlowRegistry(), txFacade);
+ StatisticsGatheringUtils.deleteAllKnownFlows(deviceContext, deviceInfo.getNodeInstanceIdentifier()
+ .augmentation(FlowCapableNode.class), false);
- verify(txFacade).writeToTransaction(
+ verify(deviceContext).writeToTransaction(
LogicalDatastoreType.OPERATIONAL,
tablePath,
tableDataBld.setFlow(Collections.<Flow>emptyList()).build());
};
Mockito.when(rqContextStack.<Object>createRequestContext()).thenReturn(rqContext);
- Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting();
+ Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(null);
Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(Matchers.any(EventIdentifier.class));
}
}
Mockito.when(deviceContext.getDeviceInfo()).thenReturn(deviceInfo);
Mockito.when(deviceInfo.getNodeId()).thenReturn(NODE_ID);
Mockito.when(deviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
- Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting();
+ Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(null);
Mockito.doAnswer(closeRequestFutureAnswer).when(multiMsgCollector).endCollecting(Matchers.any(EventIdentifier.class));
Mockito.doAnswer(answerVoidToCallback).when(outboundQueueProvider)
import org.mockito.Mockito;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
public class StatisticsGatheringOnTheFlyServiceTest extends ServiceMocking {
public static final NodeId NODE_ID = new NodeId(DUMMY_NODE_ID);
- private StatisticsGatheringOnTheFlyService statisticsGatheringService;
+ private StatisticsGatheringOnTheFlyService<MultipartReply> statisticsGatheringService;
@Override
protected void setup() {
final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
- statisticsGatheringService = new StatisticsGatheringOnTheFlyService(mockedRequestContextStack, mockedDeviceContext, convertorManager);
+ statisticsGatheringService = new StatisticsGatheringOnTheFlyService<>(mockedRequestContextStack, mockedDeviceContext, convertorManager, MultipartWriterProviderFactory.createDefaultProvider(mockedDeviceContext));
Mockito.doReturn(NODE_ID).when(mockedPrimConnectionContext).getNodeId();
Mockito.when(mockedDeviceInfo.getNodeId()).thenReturn(NODE_ID);
Mockito.when(mockedDeviceContext.getDeviceInfo().getNodeId()).thenReturn(NODE_ID);
Assert.assertEquals(xidValue, request.getXid().longValue());
Assert.assertNotNull(request);
}
-}
\ No newline at end of file
+}
import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider;
+import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProviderFactory;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
protected NodeConnectorId nodeConnectorId;
protected KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
protected ConvertorManager convertorManager;
-
+ protected MultipartWriterProvider multipartWriterProvider;
protected static NodeRef createNodeRef(String nodeIdValue) {
InstanceIdentifier<Node> nodePath = InstanceIdentifier.create(Nodes.class)
.child(Node.class, new NodeKey(new NodeId(nodeIdValue)));
.child(Node.class, new NodeKey(new NodeId(NODE_ID)));
convertorManager = ConvertorManagerFactory.createDefaultManager();
-
when(deviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
when(deviceContext.getMessageSpy()).thenReturn(messageSpy);
when(deviceContext.getMultiMsgCollector(any())).thenReturn(multiMsgCollector);
when(connectionContext.getOutboundQueueProvider()).thenReturn(outboundQueueProvider);
when(features.getVersion()).thenReturn(OF_VERSION);
when(features.getDatapathId()).thenReturn(DATAPATH_ID);
+ multipartWriterProvider = MultipartWriterProviderFactory.createDefaultProvider(deviceContext);
setUp();
}
@Test
public abstract void testStoreStatistics() throws Exception;
-}
\ No newline at end of file
+}
@RunWith(MockitoJUnitRunner.class)
public class OpendaylightDirectStatisticsServiceImplTest {
@Mock
- FlowDirectStatisticsService flowDirectStatisticsService;
+ AbstractFlowDirectStatisticsService flowDirectStatisticsService;
@Mock
- GroupDirectStatisticsService groupDirectStatisticsService;
+ AbstractGroupDirectStatisticsService groupDirectStatisticsService;
@Mock
- MeterDirectStatisticsService meterDirectStatisticsService;
+ AbstractMeterDirectStatisticsService meterDirectStatisticsService;
@Mock
- NodeConnectorDirectStatisticsService nodeConnectorDirectStatisticsService;
+ AbstractPortDirectStatisticsService nodeConnectorDirectStatisticsService;
@Mock
- QueueDirectStatisticsService queueDirectStatisticsService;
+ AbstractQueueDirectStatisticsService queueDirectStatisticsService;
@Mock
GetGroupStatisticsInput getGroupStatisticsInput;
GetMeterStatisticsInput getMeterStatisticsInput;
@Mock
GetNodeConnectorStatisticsInput getNodeConnectorStatisticsInput;
-
+
private OpendaylightDirectStatisticsService service;
private OpendaylightDirectStatisticsService emptyService;
@Before
public void setUp() throws Exception {
final OpendaylightDirectStatisticsServiceProvider provider = new OpendaylightDirectStatisticsServiceProvider();
- provider.register(FlowDirectStatisticsService.class, flowDirectStatisticsService);
- provider.register(GroupDirectStatisticsService.class, groupDirectStatisticsService);
- provider.register(MeterDirectStatisticsService.class, meterDirectStatisticsService);
- provider.register(NodeConnectorDirectStatisticsService.class, nodeConnectorDirectStatisticsService);
- provider.register(QueueDirectStatisticsService.class, queueDirectStatisticsService);
+ provider.register(AbstractFlowDirectStatisticsService.class, flowDirectStatisticsService);
+ provider.register(AbstractGroupDirectStatisticsService.class, groupDirectStatisticsService);
+ provider.register(AbstractMeterDirectStatisticsService.class, meterDirectStatisticsService);
+ provider.register(AbstractPortDirectStatisticsService.class, nodeConnectorDirectStatisticsService);
+ provider.register(AbstractQueueDirectStatisticsService.class, queueDirectStatisticsService);
service = new OpendaylightDirectStatisticsServiceImpl(provider);
emptyService = new OpendaylightDirectStatisticsServiceImpl(new OpendaylightDirectStatisticsServiceProvider());
assertFalse(result.isSuccessful());
for (RpcError error : result.getErrors()) {
- assertTrue(error.getMessage().contains(GroupDirectStatisticsService.class.getSimpleName()));
+ assertTrue(error.getMessage().contains(AbstractGroupDirectStatisticsService.class.getSimpleName()));
}
verify(groupDirectStatisticsService, times(0)).handleAndReply(getGroupStatisticsInput);
assertFalse(result.isSuccessful());
for (RpcError error : result.getErrors()) {
- assertTrue(error.getMessage().contains(QueueDirectStatisticsService.class.getSimpleName()));
+ assertTrue(error.getMessage().contains(AbstractQueueDirectStatisticsService.class.getSimpleName()));
}
verify(queueDirectStatisticsService, times(0)).handleAndReply(getQueueStatisticsInput);
assertFalse(result.isSuccessful());
for (RpcError error : result.getErrors()) {
- assertTrue(error.getMessage().contains(FlowDirectStatisticsService.class.getSimpleName()));
+ assertTrue(error.getMessage().contains(AbstractFlowDirectStatisticsService.class.getSimpleName()));
}
verify(flowDirectStatisticsService, times(0)).handleAndReply(getFlowStatisticsInput);
assertFalse(result.isSuccessful());
for (RpcError error : result.getErrors()) {
- assertTrue(error.getMessage().contains(MeterDirectStatisticsService.class.getSimpleName()));
+ assertTrue(error.getMessage().contains(AbstractMeterDirectStatisticsService.class.getSimpleName()));
}
verify(meterDirectStatisticsService, times(0)).handleAndReply(getMeterStatisticsInput);
assertFalse(result.isSuccessful());
for (RpcError error : result.getErrors()) {
- assertTrue(error.getMessage().contains(NodeConnectorDirectStatisticsService.class.getSimpleName()));
+ assertTrue(error.getMessage().contains(AbstractPortDirectStatisticsService.class.getSimpleName()));
}
verify(nodeConnectorDirectStatisticsService, times(0)).handleAndReply(getNodeConnectorStatisticsInput);
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.openflowplugin.api.openflow.registry.flow.DeviceFlowRegistry;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetFlowStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
@Override
public void setUp() throws Exception {
- service = new FlowDirectStatisticsService(requestContextStack, deviceContext, convertorManager);
+ service = new FlowDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider);
final DeviceFlowRegistry registry = mock(DeviceFlowRegistry.class);
when(registry.storeIfNecessary(any())).thenReturn(new FlowId("1"));
when(deviceContext.getDeviceFlowRegistry()).thenReturn(registry);
final GetFlowStatisticsOutput output = mock(GetFlowStatisticsOutput.class);
when(output.getFlowAndStatisticsMapList()).thenReturn(stats);
- service.storeStatistics(output);
+ multipartWriterProvider.lookup(MultipartType.OFPMPFLOW).get().write(output, true);
verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any());
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetGroupStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup;
@Override
public void setUp() throws Exception {
- service = new GroupDirectStatisticsService(requestContextStack, deviceContext, convertorManager);
+ service = new GroupDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider);
}
@Override
final GetGroupStatisticsOutput output = mock(GetGroupStatisticsOutput.class);
when(output.getGroupStats()).thenReturn(stats);
- service.storeStatistics(output);
+ multipartWriterProvider.lookup(MultipartType.OFPMPGROUP).get().write(output, true);
verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any());
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetMeterStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter;
@Override
public void setUp() throws Exception {
- service = new MeterDirectStatisticsService(requestContextStack, deviceContext, convertorManager);
+ service = new MeterDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider);
}
@Override
final GetMeterStatisticsOutput output = mock(GetMeterStatisticsOutput.class);
when(output.getMeterStats()).thenReturn(stats);
- service.storeStatistics(output);
+ multipartWriterProvider.lookup(MultipartType.OFPMPMETER).get().write(output, true);
verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any());
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetNodeConnectorStatisticsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.node.connector.statistics.and.port.number.map.NodeConnectorStatisticsAndPortNumberMap;
public class NodeConnectorDirectStatisticsServiceTest extends AbstractDirectStatisticsServiceTest {
- private NodeConnectorDirectStatisticsService service;
+ private PortDirectStatisticsService service;
@Override
public void setUp() throws Exception {
- service = new NodeConnectorDirectStatisticsService(requestContextStack, deviceContext, convertorManager);
+ service = new PortDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider);
}
@Override
final GetNodeConnectorStatisticsOutput output = mock(GetNodeConnectorStatisticsOutput.class);
when(output.getNodeConnectorStatisticsAndPortNumberMap()).thenReturn(stats);
- service.storeStatistics(output);
+ multipartWriterProvider.lookup(MultipartType.OFPMPPORTSTATS).get().write(output, true);
verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any());
}
-}
\ No newline at end of file
+}
/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.openflowplugin.impl.statistics.services.direct;
+package org.opendaylight.openflowplugin.impl.statistics.services.direct.multilayer;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.impl.statistics.services.direct.AbstractDirectStatisticsServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.direct.statistics.rev160511.GetQueueStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
@Override
public void setUp() throws Exception {
- service = new QueueDirectStatisticsService(requestContextStack, deviceContext, convertorManager);
+ service = new QueueDirectStatisticsService(requestContextStack, deviceContext, convertorManager, multipartWriterProvider);
}
@Override
final GetQueueStatisticsOutput output = mock(GetQueueStatisticsOutput.class);
when(output.getQueueIdAndStatisticsMap()).thenReturn(maps);
- service.storeStatistics(output);
+ multipartWriterProvider.lookup(MultipartType.OFPMPQUEUE).get().write(output, true);
verify(deviceContext).writeToTransactionWithParentsSlow(eq(LogicalDatastoreType.OPERATIONAL), any(), any());
}
-}
\ No newline at end of file
+}
+++ /dev/null
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.openflowplugin.impl.util;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
-import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue;
-import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandler;
-import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceInfo;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
-import org.opendaylight.openflowplugin.api.openflow.device.MessageTranslator;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
-import org.opendaylight.openflowplugin.api.openflow.device.TranslatorLibrary;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.DeviceInitializationPhaseHandler;
-import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
-import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
-import org.opendaylight.openflowplugin.impl.device.DeviceContextImpl;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandTypeBitmap;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReply;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDescBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.PortsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeaturesBuilder;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-
-@RunWith(MockitoJUnitRunner.class)
-public class DeviceInitializationUtilsTest {
-
- public static final String DUMMY_NODE_ID = "dummyNodeId";
- public static final NodeId NODE_ID = new NodeId(DUMMY_NODE_ID);
- private static final KeyedInstanceIdentifier<Node, NodeKey> DUMMY_NODE_II = InstanceIdentifier.create(Nodes.class)
- .child(Node.class, new NodeKey(new NodeId(DUMMY_NODE_ID)));
- private static final Short DUMMY_TABLE_ID = 1;
- private static final Long DUMMY_MAX_METER = 544L;
- private static final String DUMMY_DATAPATH_ID = "44";
- private static final Long DUMMY_PORT_NUMBER = 21L;
-
- @Mock
- CheckedFuture<Void, TransactionCommitFailedException> mockedFuture;
- @Mock
- private FeaturesReply mockFeatures;
- @Mock
- private OutboundQueue outboundQueueProvider;
- @Mock
- private DeviceInitializationPhaseHandler deviceInitPhaseHandler;
- @Mock
- private TranslatorLibrary translatorLibrary;
- @Mock
- private ConnectionContext mockConnectionContext;
- @Mock
- private ConnectionAdapter mockedConnectionAdapter;
- @Mock
- private DeviceContextImpl mockedDeviceContext;
- @Mock
- private DeviceInfo mockedDeviceInfo;
- @Mock
- private DeviceInitializationUtils deviceInitializationUtils;
- @Mock
- private DeviceInfo deviceInfo;
-
- private ConvertorManager convertorManager;
-
- @Before
- public void setUp() throws Exception {
- convertorManager = ConvertorManagerFactory.createDefaultManager();
-
- when(mockConnectionContext.getNodeId()).thenReturn(NODE_ID);
- when(mockConnectionContext.getFeatures()).thenReturn(mockFeatures);
- when(mockConnectionContext.getConnectionAdapter()).thenReturn(mockedConnectionAdapter);
- when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockConnectionContext);
- when(mockedDeviceContext.getDeviceInfo()).thenReturn(mockedDeviceInfo);
- when(mockedDeviceInfo.getNodeId()).thenReturn(NODE_ID);
-
- final Capabilities capabilitiesV13 = mock(Capabilities.class);
- final CapabilitiesV10 capabilitiesV10 = mock(CapabilitiesV10.class);
- when(mockFeatures.getCapabilities()).thenReturn(capabilitiesV13);
- when(mockFeatures.getCapabilitiesV10()).thenReturn(capabilitiesV10);
- when(mockFeatures.getDatapathId()).thenReturn(BigInteger.valueOf(21L));
- }
-
- //TODO: need to be rewritten with power mock to properly test statis class
- @Test
- public void initializeNodeInformationTest() throws Exception {
- DeviceState mockedDeviceState = mock(DeviceState.class);
- MultiMsgCollector msgCollector = mock(MultiMsgCollector.class);
- TranslatorLibrary tLibrary = mock(TranslatorLibrary.class);
-
- GetFeaturesOutput mockedFeatures = mock(GetFeaturesOutput.class);
- when(mockedFeatures.getTables()).thenReturn((short) 2);
- when(mockedDeviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
-
- when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(DUMMY_NODE_II);
- when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
- when(mockedDeviceContext.getMultiMsgCollector(Mockito.any(RequestContext.class))).thenReturn(msgCollector);
- when(mockedDeviceContext.oook()).thenReturn(tLibrary);
-
- final ConnectionContext connectionContext = buildMockConnectionContext(OFConstants.OFP_VERSION_1_0);
- when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
- }
-
- @Test
- public void chainTableTrunkWriteOF10Test() throws Exception {
- DeviceState mockedDeviceState = mock(DeviceState.class);
-
- final GetFeaturesOutput mockedFeatures = mock(GetFeaturesOutput.class);
- when(mockedFeatures.getTables()).thenReturn((short) 2);
- when(mockConnectionContext.getFeatures()).thenReturn(mockedFeatures);
-
- when(mockedDeviceInfo.getNodeInstanceIdentifier()).thenReturn(DUMMY_NODE_II);
- when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
-
- final RpcResult<List<MultipartReply>> mockedRpcResult = mock(RpcResult.class);
- when(mockedRpcResult.isSuccessful()).thenReturn(true);
- final List<RpcResult<List<MultipartReply>>> data = new ArrayList<RpcResult<List<MultipartReply>>>();
- data.add(mockedRpcResult);
- data.add(mockedRpcResult);
-
- DeviceInitializationUtils.chainTableTrunkWriteOF10(mockedDeviceContext, Futures.immediateFuture(data));
- verify(mockedDeviceContext, times(3)).writeToTransaction(any(LogicalDatastoreType.class),
- Matchers.<InstanceIdentifier<FlowCapableNode>> any(), any(FlowCapableNode.class));
- }
-
- @Test
- public void testTranslateAndWriteReplyTypeDesc() throws Exception {
- final ConnectionContext connectionContext = buildMockConnectionContext(OFConstants.OFP_VERSION_1_3);
- when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(connectionContext);
- final DeviceState deviceState = mock(DeviceState.class);
- when(mockedDeviceContext.getDeviceState()).thenReturn(deviceState);
-
- final Collection<MultipartReply> multipartReplyMessages = prepareDataforTypeDesc(mockedDeviceContext);
-
- DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPDESC, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager);
- verify(mockedDeviceContext)
- .writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(FlowCapableNode.class)), any(FlowCapableNode.class));
- }
-
- @Test
- public void translateAndWriteReplyTypeTableFeatures() throws Exception {
- when(mockedDeviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_3);
- TableFeaturesBuilder tableFeature = new TableFeaturesBuilder();
- tableFeature.setTableId(DUMMY_TABLE_ID);
- final List<TableFeatures> tableFeatures = new ArrayList<>();
- tableFeatures.add(tableFeature.build());
-
- final MultipartReplyTableFeatures multipartReplyTableFeatures = new MultipartReplyTableFeaturesBuilder().setTableFeatures(tableFeatures).build();
- final MultipartReplyTableFeaturesCaseBuilder multipartReplyTableFeaturesCaseBuilder = new MultipartReplyTableFeaturesCaseBuilder();
- multipartReplyTableFeaturesCaseBuilder.setMultipartReplyTableFeatures(multipartReplyTableFeatures);
-
- final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyTableFeaturesCaseBuilder.build()).build();
- final Set<MultipartReply> multipartReplyMessages = Collections.<MultipartReply>singleton(multipartReplyMessage);
- DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPTABLEFEATURES, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager);
- verify(mockedDeviceContext)
- .writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL),
- eq(DUMMY_NODE_II.augmentation(FlowCapableNode.class).child(Table.class, new TableKey(DUMMY_TABLE_ID))), any(Table.class));
-
- }
-
- @Test
- public void translateAndWriteReplyTypeMeterFeatures() throws Exception {
- DeviceState mockedDeviceState = mock(DeviceState.class);
- when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
-
- final MultipartReplyMeterFeaturesBuilder multipartReplyMeterFeaturesBuilder = new MultipartReplyMeterFeaturesBuilder();
- multipartReplyMeterFeaturesBuilder.setBandTypes(new MeterBandTypeBitmap(true, true));
- multipartReplyMeterFeaturesBuilder.setCapabilities(new MeterFlags(true, true, true, true));
- multipartReplyMeterFeaturesBuilder.setMaxMeter(DUMMY_MAX_METER);
-
- final MultipartReplyMeterFeaturesCaseBuilder multipartReplyMeterFeaturesCaseBuilder = new MultipartReplyMeterFeaturesCaseBuilder();
- multipartReplyMeterFeaturesCaseBuilder.setMultipartReplyMeterFeatures(multipartReplyMeterFeaturesBuilder.build());
-
- final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyMeterFeaturesCaseBuilder.build()).build();
- final Set<MultipartReply> multipartReplyMessages = Collections.<MultipartReply>singleton(multipartReplyMessage);
- DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPMETERFEATURES, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager);
- verify(mockedDeviceContext)
- .writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(NodeMeterFeatures.class)), any(NodeMeterFeatures.class));
- verify(mockedDeviceState).setMeterAvailable(eq(true));
- }
-
- @Test
- public void translateAndWriteReplyTypeGroupFeatures() throws Exception {
- MultipartReplyGroupFeaturesBuilder multipartReplyGroupFeaturesBuilder = new MultipartReplyGroupFeaturesBuilder();
- multipartReplyGroupFeaturesBuilder.setTypes(new GroupTypes(true, true, true, true));
- multipartReplyGroupFeaturesBuilder.setCapabilities(new GroupCapabilities(true, true, true, true));
- final ActionType actionType = new ActionType(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true);
- multipartReplyGroupFeaturesBuilder.setActionsBitmap(Lists.newArrayList(actionType));
-
- final MultipartReplyGroupFeatures multipartReplyGroupFeatures = multipartReplyGroupFeaturesBuilder.build();
-
- final MultipartReplyGroupFeaturesCaseBuilder multipartReplyGroupFeaturesCaseBuilder = new MultipartReplyGroupFeaturesCaseBuilder();
- multipartReplyGroupFeaturesCaseBuilder.setMultipartReplyGroupFeatures(multipartReplyGroupFeatures);
-
- final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyGroupFeaturesCaseBuilder.build()).build();
- final Set<MultipartReply> multipartReplyMessages = Collections.<MultipartReply>singleton(multipartReplyMessage);
-
- DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPGROUPFEATURES, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager);
- verify(mockedDeviceContext)
- .writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(NodeGroupFeatures.class)), any(NodeGroupFeatures.class));
- }
-
-
- @Test
- public void translateAndWriteReplyTypePortDesc() throws Exception {
- ConnectionContext mockedPrimaryConnectionContext = mock(ConnectionContext.class);
- FeaturesReply mockedFeatures = mock(FeaturesReply.class);
- when(mockedFeatures.getDatapathId()).thenReturn(new BigInteger(DUMMY_DATAPATH_ID));
- when(mockedPrimaryConnectionContext.getFeatures()).thenReturn(mockedFeatures);
- when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedPrimaryConnectionContext);
- final DeviceState mockedDeviceState = mock(DeviceState.class);
- when(mockedDeviceInfo.getVersion()).thenReturn(OFConstants.OFP_VERSION_1_0);
- when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
- final MessageTranslator mockedTranslator = mock(MessageTranslator.class);
- when(translatorLibrary.lookupTranslator(any(TranslatorKey.class))).thenReturn(mockedTranslator);
- when(mockedDeviceContext.oook()).thenReturn(translatorLibrary);
-
- final MultipartReplyPortDescBuilder multipartReplyPortDescBuilder = new MultipartReplyPortDescBuilder();
-
- final PortsBuilder portsBuilder = new PortsBuilder();
- portsBuilder.setPortNo(DUMMY_PORT_NUMBER);
-
- multipartReplyPortDescBuilder.setPorts(Lists.newArrayList(portsBuilder.build()));
-
- final MultipartReplyPortDescCaseBuilder multipartReplyPortDescCaseBuilder = new MultipartReplyPortDescCaseBuilder();
- multipartReplyPortDescCaseBuilder.setMultipartReplyPortDesc(multipartReplyPortDescBuilder.build());
-
- final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyPortDescCaseBuilder.build()).build();
- final Set<MultipartReply> multipartReplyMessages = Collections.<MultipartReply>singleton(multipartReplyMessage);
-
- DeviceInitializationUtils.translateAndWriteReply(MultipartType.OFPMPPORTDESC, mockedDeviceContext, DUMMY_NODE_II, multipartReplyMessages, convertorManager);
- verify(mockedDeviceContext).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL),
- Matchers.<InstanceIdentifier<NodeConnector>> any(), any(NodeConnector.class));
- }
-
- @Test
- public void createSuccessProcessingCallbackTest() throws Exception {
- DeviceState mockedDeviceState = mock(DeviceState.class);
- when(mockedDeviceContext.getDeviceState()).thenReturn(mockedDeviceState);
-
- final ConnectionContext connectionContext = buildMockConnectionContext(OFConstants.OFP_VERSION_1_3);
-
- final List<MultipartReply> multipartReplies = new ArrayList<>(prepareDataforTypeDesc(mockedDeviceContext));
- final RpcResult<List<MultipartReply>> result = RpcResultBuilder.<List<MultipartReply>>success(multipartReplies).build();
- ListenableFuture<RpcResult<List<MultipartReply>>> mockedRequestContextFuture = Futures.immediateFuture(result);
-
- DeviceInitializationUtils.createSuccessProcessingCallback(MultipartType.OFPMPDESC, mockedDeviceContext, DUMMY_NODE_II, mockedRequestContextFuture, convertorManager);
- verify(mockedDeviceContext).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(FlowCapableNode.class)), any(FlowCapableNode.class));
-
- final RpcResult<List<MultipartReply>> rpcResult = RpcResultBuilder.<List<MultipartReply>>failed().withError(RpcError.ErrorType.PROTOCOL, "dummy error").build();
- mockedRequestContextFuture = Futures.immediateFuture(rpcResult);
- DeviceInitializationUtils.createSuccessProcessingCallback(MultipartType.OFPMPDESC, mockedDeviceContext, DUMMY_NODE_II, mockedRequestContextFuture, convertorManager);
- verify(mockedDeviceContext).writeToTransaction(eq(LogicalDatastoreType.OPERATIONAL), eq(DUMMY_NODE_II.augmentation(FlowCapableNode.class)), any(FlowCapableNode.class));
- }
-
- private Collection<MultipartReply> prepareDataforTypeDesc(final DeviceContext mockedDeviceContext) {
- final MultipartReplyDesc multipartReplyDesc = new MultipartReplyDescBuilder().build();
-
- final MultipartReplyDescCaseBuilder multipartReplyDescCaseBuilder = new MultipartReplyDescCaseBuilder();
- multipartReplyDescCaseBuilder.setMultipartReplyDesc(multipartReplyDesc);
-
- final MultipartReplyMessage multipartReplyMessage = new MultipartReplyMessageBuilder().setMultipartReplyBody(multipartReplyDescCaseBuilder.build()).build();
- return Collections.<MultipartReply>singleton(multipartReplyMessage);
-
- }
-
- protected ConnectionContext buildMockConnectionContext(final short ofpVersion) {
- when(mockFeatures.getVersion()).thenReturn(ofpVersion);
- when(outboundQueueProvider.reserveEntry()).thenReturn(43L);
- Mockito.doAnswer(new Answer<Void>() {
- @Override
- public Void answer(final InvocationOnMock invocation) throws Throwable {
- final FutureCallback<OfHeader> callBack = (FutureCallback<OfHeader>) invocation.getArguments()[2];
- callBack.onSuccess(null);
- return null;
- }
- })
- .when(outboundQueueProvider)
- .commitEntry(Matchers.anyLong(), Matchers.<MultipartRequestInput>any(), Matchers.<FutureCallback<OfHeader>>any());
-
- when(mockedConnectionAdapter.registerOutboundQueueHandler(Matchers.<OutboundQueueHandler>any(), Matchers.anyInt(), Matchers.anyLong()))
- .thenAnswer(new Answer<OutboundQueueHandlerRegistration<OutboundQueueHandler>>() {
- @Override
- public OutboundQueueHandlerRegistration<OutboundQueueHandler> answer(final InvocationOnMock invocation) throws Throwable {
- final OutboundQueueHandler handler = (OutboundQueueHandler) invocation.getArguments()[0];
- handler.onConnectionQueueChanged(outboundQueueProvider);
- return null;
- }
- });
-
- when(mockConnectionContext.getOutboundQueueProvider()).thenReturn(outboundQueueProvider);
- return mockConnectionContext;
- }
-}