/** * Copyright (c) 2013 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.openflow.md.core.sal; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.Future; import org.opendaylight.controller.sal.common.util.Rpcs; import org.opendaylight.openflowjava.protocol.api.util.BinContent; import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.GroupConvertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.MeterConvertor; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PortConvertor; import org.opendaylight.openflowplugin.openflow.md.core.session.IMessageDispatchService; import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.port.mod.port.Port; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupFeaturesOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupStatisticsOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterStatisticsOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterFeaturesOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetMeterStatisticsOutputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Group; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Meter; 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.oxm.rev130731.oxm.fields.MatchEntries; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.GetPortOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.port.service.rev131107.UpdatePortOutputBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import com.google.common.util.concurrent.Futures; /** * RPC implementation of MD-switch */ public class ModelDrivenSwitchImpl extends AbstractModelDrivenSwitch { private static final Logger LOG = org.slf4j.LoggerFactory .getLogger(ModelDrivenSwitchImpl.class); private final NodeId nodeId; private final IMessageDispatchService messageService ; private short version = 0; protected ModelDrivenSwitchImpl(NodeId nodeId, InstanceIdentifier identifier, SessionContext context) { super(identifier, context); this.nodeId = nodeId; messageService = sessionContext.getMessageDispatchService() ; version = context.getPrimaryConductor().getVersion(); } @Override public Future> addFlow(AddFlowInput input) { // Convert the AddFlowInput to FlowModInput FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input, version); // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the FlowMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for AddFlow RPC" + ex.getMessage()); } UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult() ; AddFlowOutputBuilder addFlowOutput = new AddFlowOutputBuilder() ; addFlowOutput.setTransactionId(updateFlowOutput.getTransactionId()) ; AddFlowOutput result = addFlowOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Add Flow RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public Future> addGroup(AddGroupInput input) { // Convert the AddGroupInput to GroupModInput GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input, version); // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the GroupMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for AddGroup RPC" + ex.getMessage()); } UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult() ; AddGroupOutputBuilder addGroupOutput = new AddGroupOutputBuilder() ; addGroupOutput.setTransactionId(updateGroupOutput.getTransactionId()) ; AddGroupOutput result = addGroupOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Add Group RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public Future> addMeter(AddMeterInput input) { // Convert the AddMeterInput to MeterModInput MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input, version); // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the MeterMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for AddMeter RPC" + ex.getMessage()); } UpdateMeterOutput updateMeterOutput = rpcResultFromOFLib.getResult() ; AddMeterOutputBuilder addMeterOutput = new AddMeterOutputBuilder() ; addMeterOutput.setTransactionId(updateMeterOutput.getTransactionId()) ; AddMeterOutput result = addMeterOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Add Meter RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public Future> removeFlow(RemoveFlowInput input) { // Convert the RemoveFlowInput to FlowModInput FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input, version); // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the FlowMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for remove Flow RPC" + ex.getMessage()); } UpdateFlowOutput updateFlowOutput = rpcResultFromOFLib.getResult() ; RemoveFlowOutputBuilder removeFlowOutput = new RemoveFlowOutputBuilder() ; removeFlowOutput.setTransactionId(updateFlowOutput.getTransactionId()) ; RemoveFlowOutput result = removeFlowOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Remove Flow RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public Future> removeGroup( RemoveGroupInput input) { // Convert the RemoveGroupInput to GroupModInput GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input, version); // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the GroupMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for RemoveGroup RPC" + ex.getMessage()); } UpdateGroupOutput updateGroupOutput = rpcResultFromOFLib.getResult() ; RemoveGroupOutputBuilder removeGroupOutput = new RemoveGroupOutputBuilder() ; removeGroupOutput.setTransactionId(updateGroupOutput.getTransactionId()) ; RemoveGroupOutput result = removeGroupOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Remove Group RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public Future> removeMeter( RemoveMeterInput input) { // Convert the RemoveMeterInput to MeterModInput MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input, version); // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the MeterMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for RemoveMeter RPC" + ex.getMessage()); } UpdateMeterOutput updatemeterOutput = rpcResultFromOFLib.getResult() ; RemoveMeterOutputBuilder removeMeterOutput = new RemoveMeterOutputBuilder() ; removeMeterOutput.setTransactionId(updatemeterOutput.getTransactionId()) ; RemoveMeterOutput result = removeMeterOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Remove Meter RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public Future> transmitPacket(TransmitPacketInput input) { // TODO Auto-generated method stub return null; } private FlowModInputBuilder toFlowModInputBuilder(Flow source) { FlowModInputBuilder target = new FlowModInputBuilder(); target.setCookie(source.getCookie()); target.setIdleTimeout(source.getIdleTimeout()); target.setHardTimeout(source.getHardTimeout()); target.setMatch(toMatch(source.getMatch())); return target; } private Match toMatch( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) { MatchBuilder target = new MatchBuilder(); target.setMatchEntries(toMatchEntries(match)); return null; } private List toMatchEntries( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match match) { List entries = new ArrayList<>(); return null; } @Override public Future> updateFlow(UpdateFlowInput input) { // Convert the UpdateFlowInput to FlowModInput FlowModInput ofFlowModInput = FlowConvertor.toFlowModInput(input.getUpdatedFlow(), version); // Call the RPC method on MessageDispatchService // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the FlowMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.flowMod(ofFlowModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for UpdateFlow RPC" + ex.getMessage()); } UpdateFlowOutput updateFlowOutputOFLib = rpcResultFromOFLib.getResult() ; UpdateFlowOutputBuilder updateFlowOutput = new UpdateFlowOutputBuilder() ; updateFlowOutput.setTransactionId(updateFlowOutputOFLib.getTransactionId()) ; UpdateFlowOutput result = updateFlowOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Update Flow RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public Future> updateGroup( UpdateGroupInput input) { // Convert the UpdateGroupInput to GroupModInput GroupModInput ofGroupModInput = GroupConvertor.toGroupModInput(input.getUpdatedGroup(), version); // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the GroupMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.groupMod(ofGroupModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for updateGroup RPC" + ex.getMessage()); } UpdateGroupOutput updateGroupOutputOFLib = rpcResultFromOFLib.getResult() ; UpdateGroupOutputBuilder updateGroupOutput = new UpdateGroupOutputBuilder() ; updateGroupOutput.setTransactionId(updateGroupOutputOFLib.getTransactionId()) ; UpdateGroupOutput result = updateGroupOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Update Group RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public Future> updateMeter( UpdateMeterInput input) { // Convert the UpdateMeterInput to MeterModInput MeterModInput ofMeterModInput = MeterConvertor.toMeterModInput(input.getUpdatedMeter(), version); // For Meter provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; LOG.debug("Calling the MeterMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.meterMod(ofMeterModInput, cookie) ; RpcResult rpcResultFromOFLib = null ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for UpdateMeter RPC" + ex.getMessage()); } UpdateMeterOutput updateMeterOutputFromOFLib = rpcResultFromOFLib.getResult() ; UpdateMeterOutputBuilder updateMeterOutput = new UpdateMeterOutputBuilder() ; updateMeterOutput.setTransactionId(updateMeterOutputFromOFLib.getTransactionId()) ; UpdateMeterOutput result = updateMeterOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Update Meter RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } @Override public NodeId getNodeId() { return nodeId; } /* * Methods for requesting statistics from switch */ @Override public Future> getAllGroupStatistics(GetAllGroupStatisticsInput input) { //Generate xid to associate it with the request Long xid = this.getSessionContext().getNextXid(); LOG.debug("Prepare statistics request for all the groups - Transaction id - {}",xid); // Create multipart request header MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); mprInput.setType(MultipartType.OFPMPGROUP); mprInput.setVersion(version); mprInput.setXid(xid); mprInput.setFlags(new MultipartRequestFlags(false)); // Create multipart request body for fetch all the group stats MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder(); mprGroupBuild.setGroupId(BinContent.intToUnsignedLong(Group.OFPGALL.getIntValue())); //Set request body to main multipart request mprInput.setMultipartRequestBody(mprGroupBuild.build()); //Send the request, no cookies associated, use any connection LOG.debug("Send group statistics request to the switch :{}",mprGroupBuild); this.messageService.multipartRequest(mprInput.build(), null); // Prepare rpc return output. Set xid and send it back. LOG.debug("Return results and transaction id back to caller"); GetAllGroupStatisticsOutputBuilder output = new GetAllGroupStatisticsOutputBuilder(); output.setTransactionId(generateTransactionId(xid)); output.setGroupStats(null); Collection errors = Collections.emptyList(); RpcResult rpcResult = Rpcs.getRpcResult(true, output.build(), errors); return Futures.immediateFuture(rpcResult); } @Override public Future> getGroupDescription(GetGroupDescriptionInput input) { //Generate xid to associate it with the request Long xid = this.getSessionContext().getNextXid(); LOG.debug("Prepare group description statistics request - Transaction id - {}",xid); // Create multipart request header MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); mprInput.setType(MultipartType.OFPMPGROUPDESC); mprInput.setVersion(version); mprInput.setXid(xid); mprInput.setFlags(new MultipartRequestFlags(false)); // Create multipart request body for fetch all the group description stats MultipartRequestGroupDescBuilder mprGroupDescBuild = new MultipartRequestGroupDescBuilder(); //Set request body to main multipart request mprInput.setMultipartRequestBody(mprGroupDescBuild.build()); //Send the request, no cookies associated, use any connection LOG.debug("Send group desciption statistics request to switch : {}",mprGroupDescBuild); this.messageService.multipartRequest(mprInput.build(), null); // Prepare rpc return output. Set xid and send it back. LOG.debug("Return results and transaction id back to caller"); GetGroupDescriptionOutputBuilder output = new GetGroupDescriptionOutputBuilder(); output.setTransactionId(generateTransactionId(xid)); output.setGroupDescStats(null); Collection errors = Collections.emptyList(); RpcResult rpcResult = Rpcs.getRpcResult(true, output.build(), errors); return Futures.immediateFuture(rpcResult); } @Override public Future> getGroupFeatures(GetGroupFeaturesInput input) { //Generate xid to associate it with the request Long xid = this.getSessionContext().getNextXid(); LOG.debug("Prepare group features statistics request - Transaction id - {}",xid); // Create multipart request header MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); mprInput.setType(MultipartType.OFPMPGROUPFEATURES); mprInput.setVersion(version); mprInput.setXid(xid); mprInput.setFlags(new MultipartRequestFlags(false)); // Create multipart request body for fetch all the group description stats MultipartRequestGroupFeaturesBuilder mprGroupFeaturesBuild = new MultipartRequestGroupFeaturesBuilder(); //Set request body to main multipart request mprInput.setMultipartRequestBody(mprGroupFeaturesBuild.build()); //Send the request, no cookies associated, use any connection LOG.debug("Send group features statistics request :{}",mprGroupFeaturesBuild); this.messageService.multipartRequest(mprInput.build(), null); // Prepare rpc return output. Set xid and send it back. LOG.debug("Return results and transaction id back to caller"); GetGroupFeaturesOutputBuilder output = new GetGroupFeaturesOutputBuilder(); output.setTransactionId(generateTransactionId(xid)); Collection errors = Collections.emptyList(); RpcResult rpcResult = Rpcs.getRpcResult(true, output.build(), errors); return Futures.immediateFuture(rpcResult); } @Override public Future> getGroupStatistics(GetGroupStatisticsInput input) { //Generate xid to associate it with the request Long xid = this.getSessionContext().getNextXid(); LOG.debug("Prepare statistics request for node {} group ({}) - Transaction id - {}",input.getNode(),input.getGroupId(),xid); // Create multipart request header MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); mprInput.setType(MultipartType.OFPMPGROUP); mprInput.setVersion(version); mprInput.setXid(xid); mprInput.setFlags(new MultipartRequestFlags(false)); // Create multipart request body for fetch all the group stats MultipartRequestGroupBuilder mprGroupBuild = new MultipartRequestGroupBuilder(); mprGroupBuild.setGroupId(input.getGroupId().getValue()); //Set request body to main multipart request mprInput.setMultipartRequestBody(mprGroupBuild.build()); //Send the request, no cookies associated, use any connection LOG.debug("Send group statistics request :{}",mprGroupBuild); this.messageService.multipartRequest(mprInput.build(), null); // Prepare rpc return output. Set xid and send it back. LOG.debug("Return results and transaction id back to caller"); GetGroupStatisticsOutputBuilder output = new GetGroupStatisticsOutputBuilder(); output.setTransactionId(generateTransactionId(xid)); output.setGroupStats(null); Collection errors = Collections.emptyList(); RpcResult rpcResult = Rpcs.getRpcResult(true, output.build(), errors); return Futures.immediateFuture(rpcResult); } @Override public Future> getAllMeterConfigStatistics( GetAllMeterConfigStatisticsInput input) { //Generate xid to associate it with the request Long xid = this.getSessionContext().getNextXid(); LOG.debug("Prepare config request for all the meters - Transaction id - {}",xid); // Create multipart request header MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); mprInput.setType(MultipartType.OFPMPMETERCONFIG); mprInput.setVersion(version); mprInput.setXid(xid); mprInput.setFlags(new MultipartRequestFlags(false)); // Create multipart request body for fetch all the meter stats MultipartRequestMeterConfigBuilder mprMeterConfigBuild = new MultipartRequestMeterConfigBuilder(); mprMeterConfigBuild.setMeterId(BinContent.intToUnsignedLong(Meter.OFPMALL.getIntValue())); //Set request body to main multipart request mprInput.setMultipartRequestBody(mprMeterConfigBuild.build()); //Send the request, no cookies associated, use any connection LOG.debug("Send meter statistics request :{}",mprMeterConfigBuild); this.messageService.multipartRequest(mprInput.build(), null); // Prepare rpc return output. Set xid and send it back. LOG.debug("Return results and transaction id back to caller"); GetAllMeterConfigStatisticsOutputBuilder output = new GetAllMeterConfigStatisticsOutputBuilder(); output.setTransactionId(generateTransactionId(xid)); output.setMeterConfigStats(null); Collection errors = Collections.emptyList(); RpcResult rpcResult = Rpcs.getRpcResult(true, output.build(), errors); return Futures.immediateFuture(rpcResult); } @Override public Future> getAllMeterStatistics(GetAllMeterStatisticsInput input) { //Generate xid to associate it with the request Long xid = this.getSessionContext().getNextXid(); LOG.debug("Prepare statistics request for all the meters - Transaction id - {}",xid); // Create multipart request header MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); mprInput.setType(MultipartType.OFPMPMETER); mprInput.setVersion(version); mprInput.setXid(xid); mprInput.setFlags(new MultipartRequestFlags(false)); // Create multipart request body for fetch all the meter stats MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder(); mprMeterBuild.setMeterId(BinContent.intToUnsignedLong(Meter.OFPMALL.getIntValue())); //Set request body to main multipart request mprInput.setMultipartRequestBody(mprMeterBuild.build()); //Send the request, no cookies associated, use any connection LOG.debug("Send meter statistics request :{}",mprMeterBuild); this.messageService.multipartRequest(mprInput.build(), null); // Prepare rpc return output. Set xid and send it back. LOG.debug("Return results and transaction id back to caller"); GetAllMeterStatisticsOutputBuilder output = new GetAllMeterStatisticsOutputBuilder(); output.setTransactionId(generateTransactionId(xid)); output.setMeterStats(null); Collection errors = Collections.emptyList(); RpcResult rpcResult = Rpcs.getRpcResult(true, output.build(), errors); return Futures.immediateFuture(rpcResult); } @Override public Future> getMeterFeatures(GetMeterFeaturesInput input) { //Generate xid to associate it with the request Long xid = this.getSessionContext().getNextXid(); LOG.debug("Prepare features statistics request for all the meters - Transaction id - {}",xid); // Create multipart request header MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); mprInput.setType(MultipartType.OFPMPMETERFEATURES); mprInput.setVersion(version); mprInput.setXid(xid); mprInput.setFlags(new MultipartRequestFlags(false)); // Create multipart request body for fetch all the group description stats MultipartRequestMeterFeaturesBuilder mprMeterFeaturesBuild = new MultipartRequestMeterFeaturesBuilder(); //Set request body to main multipart request mprInput.setMultipartRequestBody(mprMeterFeaturesBuild.build()); //Send the request, no cookies associated, use any connection LOG.debug("Send meter features statistics request :{}",mprMeterFeaturesBuild); this.messageService.multipartRequest(mprInput.build(), null); // Prepare rpc return output. Set xid and send it back. LOG.debug("Return results and transaction id back to caller"); GetMeterFeaturesOutputBuilder output = new GetMeterFeaturesOutputBuilder(); output.setTransactionId(generateTransactionId(xid)); Collection errors = Collections.emptyList(); RpcResult rpcResult = Rpcs.getRpcResult(true, output.build(), errors); return Futures.immediateFuture(rpcResult); } @Override public Future> getMeterStatistics(GetMeterStatisticsInput input) { //Generate xid to associate it with the request Long xid = this.getSessionContext().getNextXid(); LOG.debug("Preprae statistics request for Meter ({}) - Transaction id - {}",input.getMeterId().getValue(),xid); // Create multipart request header MultipartRequestInputBuilder mprInput = new MultipartRequestInputBuilder(); mprInput.setType(MultipartType.OFPMPMETER); mprInput.setVersion(version); mprInput.setXid(xid); mprInput.setFlags(new MultipartRequestFlags(false)); // Create multipart request body for fetch all the meter stats MultipartRequestMeterBuilder mprMeterBuild = new MultipartRequestMeterBuilder(); //Select specific meter mprMeterBuild.setMeterId(input.getMeterId().getValue()); //Set request body to main multipart request mprInput.setMultipartRequestBody(mprMeterBuild.build()); //Send the request, no cookies associated, use any connection LOG.debug("Send meter statistics request :{}",mprMeterBuild); this.messageService.multipartRequest(mprInput.build(), null); // Prepare rpc return output. Set xid and send it back. LOG.debug("Return results and transaction id back to caller"); GetMeterStatisticsOutputBuilder output = new GetMeterStatisticsOutputBuilder(); output.setTransactionId(generateTransactionId(xid)); output.setMeterStats(null); Collection errors = Collections.emptyList(); RpcResult rpcResult = Rpcs.getRpcResult(true, output.build(), errors); return Futures.immediateFuture(rpcResult); } private TransactionId generateTransactionId(Long xid){ String stringXid =xid.toString(); BigInteger bigIntXid = new BigInteger( stringXid ); return new TransactionId(bigIntXid); } @Override public Future> getPort() { // TODO Auto-generated method stub return null; } @Override public Future> updatePort(UpdatePortInput input) { PortModInput ofPortModInput = null ; RpcResult rpcResultFromOFLib = null ; // For Flow provisioning, the SwitchConnectionDistinguisher is set to null so // the request can be routed through any connection to the switch SwitchConnectionDistinguisher cookie = null ; // NSF sends a list of port and the ModelDrivenSwitch will // send one port at a time towards the switch ( mutiple RPCs calls) List inputPorts = input.getUpdatedPort().getPort().getPort() ; // Get the Xid. The same Xid has to be sent in all the RPCs Long Xid = sessionContext.getNextXid(); for( Port inputPort : inputPorts) { // Convert the UpdateGroupInput to GroupModInput ofPortModInput = PortConvertor.toPortModInput(inputPort, version) ; // Insert the Xid ( transaction Id) before calling the RPC on the OFLibrary PortModInputBuilder mdInput = new PortModInputBuilder(); mdInput.setXid(Xid); mdInput.setVersion(ofPortModInput.getVersion()) ; mdInput.setPortNo(ofPortModInput.getPortNo()) ; mdInput.setMaskV10(ofPortModInput.getMaskV10()) ; mdInput.setMask(ofPortModInput.getMask()) ; mdInput.setHwAddress(ofPortModInput.getHwAddress()); mdInput.setConfigV10(ofPortModInput.getConfigV10()) ; mdInput.setConfig(ofPortModInput.getConfig()) ; mdInput.setAdvertiseV10(ofPortModInput.getAdvertiseV10()) ; mdInput.setAdvertise(ofPortModInput.getAdvertise()) ; LOG.debug("Calling the PortMod RPC method on MessageDispatchService"); Future> resultFromOFLib = messageService.portMod(ofPortModInput, cookie) ; try { rpcResultFromOFLib = resultFromOFLib.get(); } catch( Exception ex ) { LOG.error( " Error while getting result for updatePort RPC" + ex.getMessage()); } // The Future response value for all the RPCs except the last one is ignored } //Extract the Xid only from the Future for the last RPC and // send it back to the NSF UpdatePortOutput updatePortOutputOFLib = rpcResultFromOFLib.getResult() ; UpdatePortOutputBuilder updatePortOutput = new UpdatePortOutputBuilder() ; updatePortOutput.setTransactionId(updatePortOutputOFLib.getTransactionId()) ; UpdatePortOutput result = updatePortOutput.build(); Collection errors = rpcResultFromOFLib.getErrors() ; RpcResult rpcResult = Rpcs.getRpcResult(true, result, errors); LOG.debug("Returning the Update Group RPC result to MD-SAL"); return Futures.immediateFuture(rpcResult); } }