2 * @brief Serviceholder class implementation. This class holds Service and OldService lists.
6 * @copyright Intra2net AG
10 #include "serviceholder.hpp"
14 #include <boost/foreach.hpp>
15 #include <boost/filesystem.hpp>
17 #define OBJECT_FILE "/var/state/bpdyndnsd/bpdyndnsd.state"
21 namespace fs = boost::filesystem;
25 * Default constructor.
27 Serviceholder::Serviceholder()
35 * Constructor with Logger object.
37 Serviceholder::Serviceholder(Logger::Ptr _log)
45 * Default destructor. While serializing and deserializing we use boost/shared_ptr, the resources are managed correctly.
47 Serviceholder::~Serviceholder()
53 * This function serializes all Service objects in Services and OldServices (where the update Timeout isn't expired) into a specified file.
54 * @return 0 if all is fine, -1 if output file could not be opened for reading or error while serializing.
56 int Serviceholder::serialize_services() const
58 // Put Services and OldServices into Serviceholder.
59 SerializeServiceContainer::Ptr service_container(new SerializeServiceContainer);
61 BOOST_FOREACH(const Service::Ptr &service, Services)
63 service_container->add_service(service);
66 time_t current_time = time(NULL);
68 BOOST_FOREACH(const Service::Ptr &service, OldServices)
70 if ( !service->get_last_updates().empty() &&
71 ( service->get_last_updates().front() + ((time_t)service->get_update_interval()*60) ) >= current_time ) /*lint !e1793 */ // UpdateInterval timeout of service isn't expired.
72 service_container->add_service(service);
75 // Serialize SerializeServiceContainer and IPAddrHelper into file.
76 ofstream ofs(OBJECT_FILE);
79 SerializeServiceContainer* _service_container = service_container.get();
80 IPAddrHelper* _ip_addr_helper = IPAddrHelp.get();
83 boost::archive::text_oarchive oa(ofs);
84 oa << _service_container << _ip_addr_helper;
86 catch( const boost::archive::archive_exception& e )
88 Log->print_exception_serialize(e.what());
97 Log->print_error_opening_rw(OBJECT_FILE);
101 Log->print_serialized_objects_success();
108 * This function de-serializes the SerializeServiceContainer (containing Services) from the object file.
109 * @return 0 if all is fine, -1 if object file couldn't be opened for reading or error while de-serializing.
111 int Serviceholder::deserialize_services()
113 // test if OBJECT_FILE exists
114 fs::path object_file = fs::system_complete(fs::path(OBJECT_FILE));
115 if ( !fs::exists(object_file) )
117 // There is no object file, possibly first program start, continue without recovering old Services' state.
118 Log->print_no_object_file(OBJECT_FILE);
122 ifstream ifs(OBJECT_FILE);
125 // deserialize SerializeServiceContainer
126 SerializeServiceContainer* _service_container;
127 IPAddrHelper* _ip_addr_helper;
130 boost::archive::text_iarchive ia(ifs);
131 ia >> _service_container >> _ip_addr_helper;
133 catch( const boost::archive::archive_exception& e )
135 Log->print_exception_deserialize(e.what());
139 SerializeServiceContainer::Ptr service_container(_service_container);
140 IPAddrHelp = IPAddrHelper::Ptr(_ip_addr_helper);
143 // Get the list of old Services from de-serialized SerializeServiceContainer object.
144 list<Service::Ptr> _old_services = service_container->get_containing_services();
146 // Put all de-serialized Services into OldServices member and
147 // compare new Services (generated from config file and cmd) with old Services (de-serialized from object file)
148 // if identical Service was found, adopt the value from old Service to recover Services' state.
149 BOOST_FOREACH(Service::Ptr &old_service, _old_services)
151 OldServices.push_back(old_service);
152 Log->print_service_object("Deserialized following Service object:", old_service->get_protocol(), old_service->get_hostname(), old_service->get_login() ,old_service->get_password(), old_service->get_update_interval(), old_service->get_max_updates_within_interval(), old_service->get_dns_cache_ttl() , old_service->get_actual_ip(), old_service->get_last_updates());
153 BOOST_FOREACH(Service::Ptr &service, Services)
155 if ( *service == *old_service )
157 service->set_last_updates(old_service->get_last_updates());
158 service->set_actual_ip(old_service->get_actual_ip());
159 Log->print_service_object("New Service object with adopted values:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates());
160 // We have adopted the values of the old_service. Just set lastupdated and timeout to 0, so this old_service wont be serialized.
161 old_service->set_update_interval(0);
165 Log->print_deserialized_objects_success();
169 Log->print_error_opening_r(OBJECT_FILE);
178 * Add service to internal service list.
179 * @param service Shared pointer to service object.
181 void Serviceholder::add_service(Service::Ptr service)
183 Services.push_back(service);
188 * Resets all shared Service pointers and clears the Services list.
190 void Serviceholder::delete_services()
192 BOOST_FOREACH( Service::Ptr &service, Services )
198 BOOST_FOREACH( Service::Ptr &service, OldServices )
209 * Getter for member Services
210 * @return List with shared Service pointers.
212 std::list<Service::Ptr> Serviceholder::get_services() const
219 * Set member IPAddrHelp
220 * @param _ip_addr_helper The IPAddrHelper.
222 void Serviceholder::set_ip_addr_helper(IPAddrHelper::Ptr _ip_addr_helper)
224 IPAddrHelp = _ip_addr_helper;
229 * Get member IPAddrHelp
232 IPAddrHelper::Ptr Serviceholder::get_ip_addr_helper() const