X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflowplugin-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fimpl%2Fservices%2FSalTableServiceImpl.java;h=f208c3726d5fd9f2460bc6130d9dd7b7287ef83f;hb=8e9c1f4d2f83b84549b336e7ec82e81d4130c63a;hp=f50b6e51d4dfbfb6d940aad3b01202ae42967be6;hpb=3c4699582dc3bcb0e3bb854ba4f73efacdb7f333;p=openflowplugin.git diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.java index f50b6e51d4..f208c3726d 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalTableServiceImpl.java @@ -1,37 +1,175 @@ /** * 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.List; import java.util.concurrent.Future; -import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext; +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.Xid; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.TableFeaturesConvertor; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.TableFeaturesReplyConvertor; +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.transaction.rev150304.TransactionId; +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.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; -/** - * @author joe - * - */ -public class SalTableServiceImpl extends CommonService implements SalTableService { - +public final class SalTableServiceImpl extends AbstractMultipartService implements SalTableService { private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(SalTableServiceImpl.class); + public SalTableServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext) { + super(requestContextStack, deviceContext); + } + @Override public Future> updateTable(final UpdateTableInput input) { - // LOG.debug("Calling the updateTable RPC method on MessageDispatchService"); - // - // final OFRpcTask> task = - // OFRpcTaskFactory.createUpdateTableTask( - // rpcTaskContext, input, null); - // return task.submit(); - return null; + final ListenableFuture>> multipartFuture = handleServiceCall(input); + final SettableFuture> finalFuture = SettableFuture.create(); + + class CallBackImpl implements FutureCallback>> { + @Override + public void onSuccess(final RpcResult> result) { + + if (result.isSuccessful()) { + final List multipartReplies = result.getResult(); + if (multipartReplies.isEmpty()) { + LOG.debug("Multipart reply to table features request shouldn't be empty list."); + finalFuture.set(RpcResultBuilder.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()); + writeResponseToOperationalDatastore(multipartReplies); + } + } else { + LOG.debug("OnSuccess, rpc result unsuccessful, multipart response for rpc update-table was unsuccessful."); + finalFuture.set(RpcResultBuilder.failed().withRpcErrors(result.getErrors()) + .build()); + } + } + + @Override + public void onFailure(final Throwable t) { + LOG.debug("Failure multipart response for table features request. Exception: {}", t); + finalFuture.set(RpcResultBuilder.failed() + .withError(ErrorType.RPC, "Future error", t).build()); + } + } + + Futures.addCallback(multipartFuture, new CallBackImpl()); + + return finalFuture; + } + + /** + * @param multipartReplies + */ + private void writeResponseToOperationalDatastore(final List multipartReplies) { + + final List salTableFeatures = convertToSalTableFeatures(multipartReplies); + + final DeviceContext deviceContext = getDeviceContext(); + final NodeId nodeId = deviceContext.getPrimaryConnectionContext().getNodeId(); + final InstanceIdentifier flowCapableNodeII = InstanceIdentifier.create(Nodes.class) + .child(Node.class, new NodeKey(nodeId)).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 tableFeaturesII = flowCapableNodeII + .child(Table.class, new TableKey(tableId)) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures.class, + new TableFeaturesKey(tableId)); + deviceContext.writeToTransaction(LogicalDatastoreType.OPERATIONAL, tableFeaturesII, + tableFeatureData); + } + deviceContext.submitTransaction(); } + protected static List convertToSalTableFeatures( + final List multipartReplies) { + final List 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 List salTableFeaturesPartial = TableFeaturesReplyConvertor + .toTableFeaturesReply(salTableFeatures); + salTableFeaturesAll.addAll(salTableFeaturesPartial); + 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) { + final MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); + final MultipartRequestTableFeaturesBuilder requestBuilder = new MultipartRequestTableFeaturesBuilder(); + final List ofTableFeatureList = TableFeaturesConvertor.toTableFeaturesRequest(input + .getUpdatedTable()); + requestBuilder.setTableFeatures(ofTableFeatureList); + 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(); + } }