Java tutorial
/* * 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.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 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.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.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 */ public abstract class AbstractDirectStatisticsService<I extends StoreStatsGrouping, O> extends AbstractMultipartService<I> { private final Function<RpcResult<List<MultipartReply>>, RpcResult<O>> resultTransformFunction = new Function<RpcResult<List<MultipartReply>>, 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(); } }; private final AsyncFunction<RpcResult<O>, RpcResult<O>> resultStoreFunction = new AsyncFunction<RpcResult<O>, RpcResult<O>>() { @Nullable @Override public ListenableFuture<RpcResult<O>> apply(@Nullable RpcResult<O> input) throws Exception { Preconditions.checkNotNull(input); if (input.isSuccessful()) { storeStatistics(input.getResult()); getTxFacade().submitTransaction(); // TODO: If submitTransaction will ever return future, chain it } return Futures.immediateFuture(input); } }; private final MultipartType multipartType; private final ConvertorExecutor convertorExecutor; private final OpenflowVersion ofVersion = OpenflowVersion.get(getVersion()); /** * 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 */ protected AbstractDirectStatisticsService(MultipartType multipartType, RequestContextStack requestContextStack, DeviceContext deviceContext, ConvertorExecutor convertorExecutor) { super(requestContextStack, deviceContext); this.multipartType = multipartType; this.convertorExecutor = convertorExecutor; } protected ConvertorExecutor getConvertorExecutor() { return convertorExecutor; } /** * Handle input and reply future. * * @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); if (Boolean.TRUE.equals(input.isStoreStats())) { rpcResult = Futures.transform(rpcResult, resultStoreFunction); } return rpcResult; } @Override protected OfHeader buildRequest(Xid xid, I input) throws ServiceException { return RequestInputUtils.createMultipartHeader(multipartType, xid.getValue(), getVersion()) .setMultipartRequestBody(buildRequestBody(input)).build(); } /** * Gets openflow version. * * @return the openflow version */ protected OpenflowVersion getOfVersion() { return ofVersion; } /** * Build multipart request body. * * @param input the input * @return the multipart request body */ protected 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); /** * 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; }