/* * 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 com.google.common.base.Preconditions; import com.google.common.util.concurrent.Futures; 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.md.util.OpenflowVersion; import org.opendaylight.openflowplugin.impl.datastore.MultipartWriterProvider; import org.opendaylight.openflowplugin.impl.services.AbstractMultipartService; import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor; 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.OfHeader; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.common.RpcResultBuilder; /** * The abstract direct statistics service. * This abstract service provides wrappers and tools for all other derived statistics services. * * @param <I> the input type parameter * @param <O> the output type parameter */ abstract class AbstractDirectStatisticsService<I extends StoreStatsGrouping, O extends DataContainer, T extends OfHeader> extends AbstractMultipartService<I, T> { private final MultipartType multipartType; 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 convertor executor * @param multipartWriterProvider statistics writer provider */ 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; this.multipartWriterProvider = multipartWriterProvider; } /** * Handle input and reply future. * * @param input the input * @return the future */ Future<RpcResult<O>> handleAndReply(final I input) { final ListenableFuture<RpcResult<List<T>>> rpcReply = handleServiceCall(input); ListenableFuture<RpcResult<O>> rpcResult = Futures.transform(rpcReply, this::transformResult); if (Boolean.TRUE.equals(input.isStoreStats())) { rpcResult = Futures.transform(rpcResult, this::storeResult); } return rpcResult; } private RpcResult<O> transformResult(final RpcResult<List<T>> input) { return Preconditions.checkNotNull(input).isSuccessful() ? RpcResultBuilder.success(buildReply(input.getResult(), input.isSuccessful())).build() : RpcResultBuilder.<O>failed().withRpcErrors(input.getErrors()).build(); } private RpcResult<O> storeResult(final RpcResult<O> input) { Preconditions.checkNotNull(input); if (input.isSuccessful()) { multipartWriterProvider.lookup(multipartType).ifPresent(writer -> { writer.write(input.getResult(), true); getTxFacade().submitTransaction(); }); } return input; } /** * Get multipart type * @return multipart type */ protected MultipartType getMultipartType() { return multipartType; } /** * Get convertor executor * @return convertor executor */ protected ConvertorExecutor getConvertorExecutor() { return convertorExecutor; } /** * Gets openflow version. * * @return the openflow version */ protected OpenflowVersion getOfVersion() { return ofVersion; } /** * Build output from multipart reply input. * * @param input the input * @return the output */ protected abstract O buildReply(List<T> input, boolean success); }