netconf_process.cc 3.76 KB
Newer Older
1
// Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
2 3 4 5 6 7 8
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <config.h>
#include <asiolink/asio_wrapper.h>
9
#include <netconf/netconf.h>
10 11 12 13 14 15 16 17
#include <netconf/netconf_process.h>
#include <netconf/netconf_controller.h>
#include <netconf/netconf_log.h>
#include <asiolink/io_address.h>
#include <asiolink/io_error.h>
#include <cc/command_interpreter.h>
#include <config/timeouts.h>
#include <boost/pointer_cast.hpp>
18
#include <thread>
19 20 21 22 23 24 25 26 27 28

using namespace isc::asiolink;
using namespace isc::config;
using namespace isc::data;
using namespace isc::http;
using namespace isc::process;

namespace isc {
namespace netconf {

29
std::atomic<bool> NetconfProcess::shut_down(false);
30

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
NetconfProcess::NetconfProcess(const char* name,
                               const asiolink::IOServicePtr& io_service)
    : DProcessBase(name, io_service, DCfgMgrBasePtr(new NetconfCfgMgr())) {
}

NetconfProcess::~NetconfProcess() {
}

void
NetconfProcess::init() {
}

void
NetconfProcess::run() {
    LOG_INFO(netconf_logger, NETCONF_STARTED).arg(VERSION);

    try {
48
        // Initialize netconf agent in a thread.
49
        std::thread th([this]() {
50
            try {
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
                if (shouldShutdown()) {
                    return;
                }
                // Initialize sysrepo.
                agent_.initSysrepo();
                if (shouldShutdown()) {
                    return;
                }

                // Get the configuration manager.
                NetconfCfgMgrPtr cfg_mgr;
                if (shouldShutdown()) {
                    return;
                } else {
                    cfg_mgr = getNetconfCfgMgr();
                }
67

68 69
                // Call init.
                agent_.init(cfg_mgr);
70 71 72 73 74 75 76 77 78
            } catch (...) {
                // Should not happen but in case...
                std::exception_ptr eptr = std::current_exception();
                getIoService()->post([eptr] () {
                    if (eptr) {
                        std::rethrow_exception(eptr);
                    }
                });
            }
79 80
        });

81
        // Detach the thread.
82
        th.detach();
83

84 85 86
        // Let's process incoming data or expiring timers in a loop until
        // shutdown condition is detected.
        while (!shouldShutdown()) {
87
            runIO();
88 89
        }
        stopIOService();
90

91 92 93 94 95 96 97 98 99 100 101 102 103 104
    } catch (const std::exception& ex) {
        LOG_FATAL(netconf_logger, NETCONF_FAILED).arg(ex.what());
        try {
            stopIOService();
        } catch (...) {
            // Ignore double errors
        }
        isc_throw(DProcessBaseError,
                  "Process run method failed: " << ex.what());
    }

    LOG_DEBUG(netconf_logger, isc::log::DBGLVL_START_SHUT, NETCONF_RUN_EXIT);
}

105 106 107 108 109 110 111 112 113
size_t
NetconfProcess::runIO() {
    size_t cnt = getIoService()->get_io_service().poll();
    if (!cnt) {
        cnt = getIoService()->get_io_service().run_one();
    }
    return (cnt);
}

114 115
isc::data::ConstElementPtr
NetconfProcess::shutdown(isc::data::ConstElementPtr /*args*/) {
116
    shut_down = true;
117 118 119 120 121 122 123
    setShutdownFlag(true);
    return (isc::config::createAnswer(0, "Netconf is shutting down"));
}

isc::data::ConstElementPtr
NetconfProcess::configure(isc::data::ConstElementPtr config_set,
                          bool check_only) {
124 125
    ConstElementPtr answer =
        getCfgMgr()->simpleParseConfig(config_set, check_only);
126 127 128 129 130 131 132 133 134 135 136 137
    int rcode = 0;
    config::parseAnswer(rcode, answer);
    return (answer);
}

NetconfCfgMgrPtr
NetconfProcess::getNetconfCfgMgr() {
    return (boost::dynamic_pointer_cast<NetconfCfgMgr>(getCfgMgr()));
}

} // namespace isc::netconf
} // namespace isc