org.opendaylight.iotdm.onem2m.core.Onem2mCoreProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.iotdm.onem2m.core.Onem2mCoreProvider.java

Source

/*
 * 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.iotdm.onem2m.core;

import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.Monitor;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.iotdm.onem2m.core.database.Onem2mDb;
import org.opendaylight.iotdm.onem2m.core.rest.RequestPrimitiveProcessor;
import org.opendaylight.iotdm.onem2m.core.rest.utils.RequestPrimitive;
import org.opendaylight.iotdm.onem2m.core.rest.utils.ResponsePrimitive;
import org.opendaylight.iotdm.onem2m.core.router.Onem2mRouterService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iotdm.onem2m.rev150105.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iotdm.onem2m.rev150105.onem2m.primitive.list.Onem2mPrimitive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.onem2m.core.rev141210.Onem2mCoreRuntimeMXBean;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Onem2mCoreProvider
        implements Onem2mService, Onem2mCoreRuntimeMXBean, BindingAwareProvider, AutoCloseable {

    private static final Logger LOG = LoggerFactory.getLogger(Onem2mCoreProvider.class);
    private BindingAwareBroker.RpcRegistration<Onem2mService> rpcReg;
    private DataBroker dataBroker;
    private Onem2mStats stats;
    private Onem2mDb db;
    private static NotificationPublishService notifierService;

    private Monitor crudMonitor;
    private static Onem2mRouterService routerService;

    public static NotificationPublishService getNotifier() {
        return Onem2mCoreProvider.notifierService;

    }

    /**
     * Perform session initialization
     * @param session the session
     */
    @Override
    public void onSessionInitiated(ProviderContext session) {
        this.rpcReg = session.addRpcImplementation(Onem2mService.class, this);
        this.dataBroker = session.getSALService(DataBroker.class);
        this.notifierService = session.getSALService(NotificationPublishService.class);
        crudMonitor = new Monitor();
        this.routerService = Onem2mRouterService.getInstance();

        stats = Onem2mStats.getInstance();
        db = Onem2mDb.getInstance();
        db.initializeDatastore(dataBroker);
        initializePerfCse();
        LOG.info("Session Initiated");
    }

    /**
     * Shutdown the session
     * @throws Exception general exception if bad things happen
     */
    @Override
    public void close() throws Exception {
        if (this.rpcReg != null) {
            this.rpcReg.close();
        }
        if (db != null) {
            db.close();
        }
        LOG.info("Session Closed");
    }

    private void initializePerfCse() {
        if (!Onem2mDb.getInstance().findCseByName(Onem2m.SYS_PERF_TEST_CSE)) {
            RequestPrimitiveProcessor onem2mRequest = new RequestPrimitiveProcessor();
            onem2mRequest.createUpdateDeleteMonitorSet(crudMonitor);
            onem2mRequest.setPrimitive("CSE_ID", Onem2m.SYS_PERF_TEST_CSE);
            onem2mRequest.setPrimitive("CSE_TYPE", Onem2m.CseType.INCSE);
            ResponsePrimitive onem2mResponse = new ResponsePrimitive();
            onem2mRequest.provisionCse(onem2mResponse);
        }
    }

    /**
     * This is the requestPrimitive RPC, it can be called from restconf directly, or it can be called from
     * onem2m-protocol-coap/http/mqtt.  Each of those onem2m-protocols have used the protocol specific bindings
     * to extract primitives from protocol specific fields and placed them in the List of Onem2mPrimitives.
     * See Onem2m.RequestPrimitive for the list of possible primitives.  For the most part, these primitives
     * are format independent and as such are strings.  There is one exception, ie the Onem2m.RequestPrimitive.CONTENT
     * parameter which has been serialized as a string by the onenm2m-protocols which was encoded in the payload
     * of those protocols.  The CONTENT is encoded by the Onem2m.RequestPrimitive.CONTENT_FORMAT=json/xml).  The
     * code that ultimately cares about the CONTENT will decode it using the appropriate content parser.
     * Based on the operation, mandatory fields have to be checked.
     * @param input the input request primitives
     * @return the response primitives
     */
    @Override
    public Future<RpcResult<Onem2mRequestPrimitiveOutput>> onem2mRequestPrimitive(
            Onem2mRequestPrimitiveInput input) {

        //LOG.info("RPC: begin handle op ...");

        List<Onem2mPrimitive> onem2mPrimitiveList = input.getOnem2mPrimitive();
        // todo: if it is a group/fanoutpoint, new a GroupRequestPrimitiveProcessor then called a lot of single processor?
        RequestPrimitiveProcessor onem2mRequest = new RequestPrimitiveProcessor();
        ResponsePrimitive onem2mResponse = null;
        onem2mRequest.setPrimitivesList(onem2mPrimitiveList);

        Onem2mDb.CseBaseResourceLocator resourceLocator = null;
        try {
            resourceLocator = this.db.createResourceLocator(onem2mRequest.getPrimitive(RequestPrimitive.TO));
        } catch (IllegalArgumentException ex) {
            LOG.error("Request with invalid URI passed: {}", onem2mRequest.getPrimitive(RequestPrimitive.TO));
            // rethrow the exception
            throw ex;
        }

        // Check if the target URI points to local resource
        if (!resourceLocator.isLocalResource()) {
            LOG.trace("Non-local resource requested by URI {}", resourceLocator.getTargetURI());

            try {
                onem2mResponse = routerService.forwardRequest(onem2mRequest, resourceLocator).get();
            } catch (InterruptedException | ExecutionException ex) {
                LOG.error("Forwarding procedure failed: {}", ex);
                onem2mResponse = new ResponsePrimitive();
                onem2mResponse.setPrimitive(ResponsePrimitive.REQUEST_IDENTIFIER,
                        onem2mRequest.getPrimitive(RequestPrimitive.REQUEST_IDENTIFIER));
                onem2mResponse.setRSC(Onem2m.ResponseStatusCode.INTERNAL_SERVER_ERROR,
                        "Forwarding procedure failed");
            }

        } else {
            LOG.trace("Local resource requested by URI {}", resourceLocator.getTargetURI());
            onem2mRequest.createUpdateDeleteMonitorSet(crudMonitor);
            onem2mResponse = new ResponsePrimitive();

            onem2mRequest.handleOperation(onem2mResponse);
        }

        onem2mPrimitiveList = onem2mResponse.getPrimitivesList();
        Onem2mRequestPrimitiveOutput output = new Onem2mRequestPrimitiveOutputBuilder()
                .setOnem2mPrimitive(onem2mPrimitiveList).build();

        //LOG.info("RPC: end handle op ...");

        return RpcResultBuilder.success(output).buildFuture();
    }

    /**
     * This is the cse provisioning RPC, it can be called from restconf directly.  When a cse is initially configured
     * it needs to be provisioned with the parameters of the CSE.  This can be done via an RPC, or perhaps a CONFIG
     * file in the file system?
     *
     * For now the provisioning parms supported are
     * 1 CSE_ID - the name of the cse Base
     * 2 CSE_TYPE - "IN-CSE", "...
     * @param input cse parms
     * @return cse output parms
     */
    @Override
    public Future<RpcResult<Onem2mCseProvisioningOutput>> onem2mCseProvisioning(Onem2mCseProvisioningInput input) {

        LOG.info("RPC: begin handle onem2mCseProvisioning ...");

        List<Onem2mPrimitive> csePrimitiveList = input.getOnem2mPrimitive();
        RequestPrimitiveProcessor onem2mRequest = new RequestPrimitiveProcessor();
        onem2mRequest.setPrimitivesList(csePrimitiveList);
        ResponsePrimitive onem2mResponse = new ResponsePrimitive();
        onem2mRequest.createUpdateDeleteMonitorSet(crudMonitor);

        onem2mRequest.provisionCse(onem2mResponse);

        if (onem2mResponse.getPrimitive("rsc").contains("Provisioned")) {
            RequestPrimitiveProcessor onem2mRequest1 = new RequestPrimitiveProcessor();
            onem2mRequest1.createUpdateDeleteMonitorSet(crudMonitor);
            onem2mRequest1.setPrimitivesList(csePrimitiveList);
            onem2mRequest1.createDefaultACP(onem2mResponse);
        }

        csePrimitiveList = onem2mResponse.getPrimitivesList();

        Onem2mCseProvisioningOutput output = new Onem2mCseProvisioningOutputBuilder()
                .setOnem2mPrimitive(csePrimitiveList).build();

        // TODO: modify the default acp response
        // TODO: why response return only CSE information, what about ACP?
        LOG.info("RPC: end handle onem2mCseProvisioning ...");
        return RpcResultBuilder.success(output).buildFuture();
    }

    /**
     * Cleanup the data store RPC
     * @return VOID
     */
    @Override
    public Future<RpcResult<java.lang.Void>> onem2mCleanupStore() {
        Onem2mDb.getInstance().cleanupDataStore();
        Onem2mRouterService.cleanRoutingTable();
        initializePerfCse();
        Onem2mDb.getInstance().dumpResourceIdLog(null);
        return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
    }

    /**
     * Dump the data store to karaf log RPC
     * @param input all or start resource
     * @return VOID
     */
    @Override
    public Future<RpcResult<java.lang.Void>> onem2mDumpResourceTree(Onem2mDumpResourceTreeInput input) {
        LOG.info("RPC: onem2mDumpResourceTree dumping ...");

        RequestPrimitiveProcessor onem2mRequest = new RequestPrimitiveProcessor();
        ResponsePrimitive onem2mResponse = new ResponsePrimitive();

        String resourceId;
        if (input == null || input.getResourceUri() == null || input.getResourceUri().trim().contentEquals("")) {
            resourceId = null;
        } else {
            String resourceUri = input.getResourceUri().trim();
            //onem2mRequest.setPrimitive(RequestPrimitive.TO, resourceUri);
            if (!Onem2mDb.getInstance().findResourceUsingURI(resourceUri, onem2mRequest, onem2mResponse)) {
                LOG.error("Cannot find resourceUri: {}", resourceUri);
                return Futures.immediateFuture(RpcResultBuilder.<Void>failed().build());
            }
            resourceId = onem2mRequest.getResourceId();
            LOG.info("Dumping resourceUri: {}, resourceId: {}", resourceUri, resourceId);
        }
        switch (input.getDumpMethod()) {
        case RAW:
            Onem2mDb.getInstance().dumpResourceIdLog(resourceId);
            break;
        case HIERARCHICAL:
            Onem2mDb.getInstance().dumpHResourceIdToLog(resourceId);
            break;
        default:
            LOG.error("Unknown dump method: {}", input.getDumpMethod());
            break;
        }
        return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
    }

    /**
     * This is a generic debug function ... it allows input and output parameters
     * @param input Onem2mDebugInput
     * @return returnRPC
     */
    @Override
    public Future<RpcResult<Onem2mDebugOutput>> onem2mDebug(Onem2mDebugInput input) {

        LOG.info("RPC: begin handle onem2mDebug ...");

        List<Onem2mPrimitive> onem2mPrimitiveList = input.getOnem2mPrimitive();
        RequestPrimitiveProcessor onem2mRequest = new RequestPrimitiveProcessor();
        onem2mRequest.setPrimitivesList(onem2mPrimitiveList);
        ResponsePrimitive onem2mResponse = new ResponsePrimitive();

        String op = onem2mRequest.getPrimitive("op");
        if (op == null) {
            onem2mResponse.setRSC("Unknown op", "(op) not set in input list");
        } else if (op.contentEquals("stats-get")) {
            onem2mResponse.setPrimitive("stats", getOnem2mStats());
        } else {
            onem2mResponse.setRSC("unknown op", op);
        }

        onem2mPrimitiveList = onem2mResponse.getPrimitivesList();
        Onem2mDebugOutput output = new Onem2mDebugOutputBuilder().setOnem2mPrimitive(onem2mPrimitiveList).build();

        LOG.info("RPC: end handle onem2mDebug ...");

        return RpcResultBuilder.success(output).buildFuture();
    }

    @Override
    public String getOnem2mStats() {
        return stats.getStats().toString();
    }
}