/* * Copyright (c) 2017 Serro LLC. 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.nic.of.renderer.strategy; import com.google.common.collect.Lists; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.nic.of.renderer.api.MeterQueueService; import org.opendaylight.nic.of.renderer.exception.MeterCreationExeption; import org.opendaylight.nic.of.renderer.exception.MeterRemovalExeption; import org.opendaylight.nic.of.renderer.impl.MeterQueueServiceImpl; import org.opendaylight.nic.of.renderer.utils.TopologyUtils; import org.opendaylight.nic.utils.MdsalUtils; 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.genius.idmanager.rev160406.IdManagerService; 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.meter.types.rev130918.BandId; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandType; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DropBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.MeterBandHeadersBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.meter.band.header.MeterBandTypesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.nic.renderer.api.dataflow.rev170309.Dataflow; import org.opendaylight.yang.gen.v1.urn.opendaylight.nic.renderer.api.meterid.queue.types.rev170316.MeteridObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Future; public class MeterExecutor { private static final Logger LOG = LoggerFactory.getLogger(MeterExecutor.class); private final DataBroker dataBroker; private final MdsalUtils mdsalUtils; private MeterQueueService meterQueueService; public MeterExecutor(final DataBroker dataBroker, final IdManagerService idManagerService) { this.dataBroker = dataBroker; this.mdsalUtils = new MdsalUtils(dataBroker); this.meterQueueService = new MeterQueueServiceImpl(idManagerService); } public MeterId createMeter(final Dataflow dataflow) throws MeterCreationExeption { return createMeter(dataflow.getId().getValue(), dataflow.getBandwidthRate()); } public MeterId createMeter(final String id, final long dropRate) throws MeterCreationExeption { MeterBandHeadersBuilder meterBandHeadersBuilder = new MeterBandHeadersBuilder(); MeterBandHeaderBuilder meterBandHeaderBuilder = new MeterBandHeaderBuilder(); MeterBuilder meterBuilder = new MeterBuilder(); final long meterIdLong = meterQueueService.getNextMeterId(id); final MeterId meterId = new MeterId(meterIdLong); MeterFlags meterFlags = new MeterFlags(false, true, false, false); meterBuilder.setKey(new MeterKey(meterId)); meterBuilder.setMeterId(meterId); meterBuilder.setFlags(meterFlags); int bandKey = 0; DropBuilder dropBuilder = new DropBuilder(); dropBuilder.setDropBurstSize(0L); dropBuilder.setDropRate(dropRate); MeterBandTypesBuilder meterBandTypesBuilder = new MeterBandTypesBuilder(); meterBandTypesBuilder.setFlags(new MeterBandType(true, false, false)); Drop drop = dropBuilder.build(); BandId bandId = new BandId((long)bandKey); meterBandHeaderBuilder.setBandBurstSize(drop.getDropBurstSize()); meterBandHeaderBuilder.setBandRate(drop.getDropRate()); meterBandHeaderBuilder.setKey(new MeterBandHeaderKey(bandId)); meterBandHeaderBuilder.setBandId(bandId); meterBandHeaderBuilder.setMeterBandTypes(meterBandTypesBuilder.build()); meterBandHeaderBuilder.setBandType(drop); meterBandHeadersBuilder.setMeterBandHeader(Lists.newArrayList(meterBandHeaderBuilder.build())); meterBuilder.setMeterBandHeaders(meterBandHeadersBuilder.build()); final Meter meter = meterBuilder.build(); final Map<Node, List<NodeConnector>> nodeListMap = TopologyUtils.getNodes(dataBroker); final Set<Boolean> metersCreationResults = new HashSet<>(); for (Map.Entry<Node, List<NodeConnector>> entry : nodeListMap.entrySet()) { final InstanceIdentifier<Meter> instanceIdentifier = retrieveMeterIdentifier(meterId, entry.getKey()); final boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, instanceIdentifier, meter); metersCreationResults.add(result); } //If only one meter was created with success, the result is true. if (!metersCreationResults.contains(Boolean.TRUE)) { throw new MeterCreationExeption(); } return meter.getMeterId(); } public Future<RpcResult<Void>> removeMeter(final Long meterId, String dataflowId) throws MeterRemovalExeption { boolean result = false; final MeterId id = new MeterId(meterId); final Future<RpcResult<Void>> releaseMeterResult = meterQueueService.releaseMeterId(dataflowId); final Map<Node, List<NodeConnector>> nodeListMap = TopologyUtils.getNodes(dataBroker); for (Map.Entry<Node, List<NodeConnector>> entry : nodeListMap.entrySet()) { final InstanceIdentifier<Meter> instanceIdentifier = retrieveMeterIdentifier(id, entry.getKey()); result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, instanceIdentifier); } if (!result) { throw new MeterRemovalExeption(Long.toString(meterId)); } return releaseMeterResult; } private InstanceIdentifier<Meter> retrieveMeterIdentifier(final MeterId meterId, Node node) { KeyedInstanceIdentifier<Meter, MeterKey> flowIID = null; try { final InstanceIdentifier<Node> nodePath = InstanceIdentifier .create(Nodes.class) .child(Node.class, node.getKey()); flowIID = nodePath .augmentation(FlowCapableNode.class) .child(Meter.class, new MeterKey(meterId)); } catch (Exception e) { LOG.error(e.getMessage()); } return flowIID.builder().build(); } }