2 * @brief Serviceholder class implementation. This class holds Service and OldService lists.
6 * @copyright Intra2net AG
10 #include "serviceholder.h"
14 #include <boost/foreach.hpp>
15 #include <boost/filesystem.hpp>
17 #define OBJECT_FILE "/var/local/bpdyndnsd/objects.ser"
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()
58 // Put Services and OldServices into Serviceholder.
59 SerializeServiceContainer::Ptr service_container(new SerializeServiceContainer);
61 BOOST_FOREACH(Service::Ptr &service, Services)
63 service_container->add_service(service);
66 int current_time = time(NULL);
68 BOOST_FOREACH(Service::Ptr &service, OldServices)
70 if ( ( service->get_last_updates().front() + (service->get_update_interval()*60) ) >= current_time ) // UpdateInterval timeout of service isn't expired.
71 service_container->add_service(service);
74 // Serialize SerializeServiceContainer and IPAddrHelper into file.
75 ofstream ofs(OBJECT_FILE);
78 SerializeServiceContainer* _service_container = service_container.get();
79 IPAddrHelper* _ip_addr_helper = IPAddrHelp.get();
82 boost::archive::text_oarchive oa(ofs);
83 oa << _service_container << _ip_addr_helper;
85 catch( boost::archive::archive_exception e )
87 Log->print_exception_serialize(e.what());
96 Log->print_error_opening_rw(OBJECT_FILE);
100 Log->print_serialized_objects_success();
107 * This function de-serializes the SerializeServiceContainer (containing Services) from the object file.
108 * @return 0 if all is fine, -1 if object file couldn't be opened for reading or error while de-serializing.
110 int Serviceholder::deserialize_services()
112 // test if OBJECT_FILE exists
113 fs::path object_file = fs::system_complete(fs::path(OBJECT_FILE));
114 if ( !fs::exists(object_file) )
116 // There is no object file, possibly first program start, continue without recovering old Services' state.
117 Log->print_no_object_file(OBJECT_FILE);
121 ifstream ifs(OBJECT_FILE);
124 // deserialize SerializeServiceContainer
125 SerializeServiceContainer* _service_container;
126 IPAddrHelper* _ip_addr_helper;
129 boost::archive::text_iarchive ia(ifs);
130 ia >> _service_container >> _ip_addr_helper;
132 catch( boost::archive::archive_exception e )
134 Log->print_exception_deserialize(e.what());
138 SerializeServiceContainer::Ptr service_container(_service_container);
139 IPAddrHelper::Ptr ip_addr_helper(_ip_addr_helper);
140 IPAddrHelp.swap(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