org.opendaylight.toaster.impl.ToasterServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.toaster.impl.ToasterServiceImpl.java

Source

/*
 * Copyright  2015 CopyLeft(c) 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.toaster.impl;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicReference;

import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.toaster.rev150105.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.toaster.rev150105.Toaster.ToasterStatus;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
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;
import org.slf4j.LoggerFactory;

import com.google.common.base.Optional;
import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;

import java.util.Date;
import java.text.SimpleDateFormat;
import java.lang.management.ManagementFactory;

public class ToasterServiceImpl implements ToasterService, DataChangeListener {

    private static final Logger LOG = LoggerFactory.getLogger(ToasterServiceImpl.class);

    private final AtomicReference<Future<?>> currentMakeToastTask = new AtomicReference<>();

    final InstanceIdentifier<Toaster> TOASTER_IID = InstanceIdentifier.builder(Toaster.class).build();

    private final ExecutorService executor = Executors.newFixedThreadPool(1);

    private DataBroker broker;

    public ToasterServiceImpl(DataBroker broker) {
        this.broker = broker;
    }

    @Override
    public Future<RpcResult<java.lang.Void>> cancelToast() {
        LOG.info("cancelToast");
        final InstanceIdentifier<Toaster> TOASTER_IID = InstanceIdentifier.builder(Toaster.class).build();
        final ReadWriteTransaction tx = broker.newReadWriteTransaction();
        ListenableFuture<Optional<Toaster>> readFuture = tx.read(LogicalDatastoreType.OPERATIONAL, TOASTER_IID);

        //Optional<Toaster>ListenableFuture??VoidListenableFuture
        final ListenableFuture<Void> commitFuture = Futures.transform(readFuture,
                new AsyncFunction<Optional<Toaster>, Void>() {

                    @Override
                    public ListenableFuture<Void> apply(final Optional<Toaster> toasterData) throws Exception {
                        //?toastertasterStatus
                        ToasterStatus toasterStatus = ToasterStatus.Down;
                        if (toasterData.isPresent()) {
                            toasterStatus = toasterData.get().getToasterStatus();
                        }

                        //???Up
                        if (toasterStatus == ToasterStatus.Down) {
                            //Down?
                            LOG.info("the toaster is not running!");
                            return Futures.immediateFailedCheckedFuture(new TransactionCommitFailedException("",
                                    RpcResultBuilder.newWarning(ErrorType.APPLICATION, "not-in-use",
                                            "Toaster is not running", null, null, null)));
                        } else {
                            //up??down?
                            tx.put(LogicalDatastoreType.OPERATIONAL, TOASTER_IID,
                                    new ToasterBuilder().setToasterStatus(ToasterStatus.Down).build());
                            return tx.submit();
                        }
                    }
                });

        //callback
        Futures.addCallback(commitFuture, new FutureCallback<Void>() {
            @Override
            public void onSuccess(final Void result) {
                // data store?makeToast
                LOG.info("******Task was canceled.******");
            }

            @Override
            public void onFailure(final Throwable ex) {
                LOG.debug("Failed to commit Toaster status", ex);
            }
        });
        return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
    }

    @Override
    public Future<RpcResult<java.lang.Void>> makeToast(final MakeToastInput input) {
        LOG.info("makeToast: {}", input);

        String name = ManagementFactory.getRuntimeMXBean().getName();
        LOG.info(name);
        // get pid  
        String pid = name.split("@")[0];
        LOG.info("#########pid is:" + pid);
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//?
        String time = df.format(new Date());
        LOG.info("#########time is " + time);// new Date()??
        String tid = Long.toString(Thread.currentThread().getId());
        LOG.info("#########tid is:" + tid);
        record("makeToast", time, pid, tid);

        final InstanceIdentifier<Toaster> TOASTER_IID = InstanceIdentifier.builder(Toaster.class).build();
        final ReadWriteTransaction tx = broker.newReadWriteTransaction();
        ListenableFuture<Optional<Toaster>> readFuture = tx.read(LogicalDatastoreType.OPERATIONAL, TOASTER_IID);

        //Optional<Toaster>ListenableFuture??VoidListenableFuture
        final ListenableFuture<Void> commitFuture = Futures.transform(readFuture,
                new AsyncFunction<Optional<Toaster>, Void>() {

                    @Override
                    public ListenableFuture<Void> apply(final Optional<Toaster> toasterData) throws Exception {
                        //?toastertasterStatus
                        ToasterStatus toasterStatus = ToasterStatus.Down;
                        if (toasterData.isPresent()) {
                            toasterStatus = toasterData.get().getToasterStatus();
                        }

                        //???Up
                        if (toasterStatus == ToasterStatus.Up) {
                            //Up?
                            LOG.info("the toaster is already using,please wait a moment!");
                            return Futures.immediateFailedCheckedFuture(
                                    new TransactionCommitFailedException("", RpcResultBuilder.newWarning(
                                            ErrorType.APPLICATION, "in-use", "Toaster is busy", null, null, null)));
                        } else {
                            //down??Up?
                            tx.put(LogicalDatastoreType.OPERATIONAL, TOASTER_IID,
                                    new ToasterBuilder().setToasterStatus(ToasterStatus.Up).build());
                            return tx.submit();
                        }
                    }
                });

        //callback
        Futures.addCallback(commitFuture, new FutureCallback<Void>() {
            @Override
            public void onSuccess(final Void result) {
                // data store?makeToast
                LOG.info("******Task Starts******");
                currentMakeToastTask.set(executor.submit(new MakeToastTask(input)));
            }

            @Override
            public void onFailure(final Throwable ex) {
                LOG.debug("Failed to commit Toaster status", ex);
            }
        });

        return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
    }

    @Override
    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
        DataObject dataObject = change.getUpdatedSubtree();
        if (dataObject instanceof Toaster) {
            Toaster toaster = (Toaster) dataObject;
            LOG.info("onDataChanged - new Toaster config: {}", toaster);
        }
    }

    public void record(String name, String time, String pid, String tid) {
        InstanceIdentifier<Info> INFO_IID = InstanceIdentifier.builder(Info.class).build();
        final WriteTransaction tx = broker.newWriteOnlyTransaction();
        InfoBuilder ib = new InfoBuilder();
        ib.setName(name);
        ib.setTime(time);
        ib.setPid(pid);
        ib.setTid(tid);
        tx.put(LogicalDatastoreType.OPERATIONAL, INFO_IID, ib.build());
        tx.submit();
    }
}