2 * @brief Serviceholder class implementation. This class holds Service and OldService lists.
6 * @copyright Intra2net AG
10 #include "serviceholder.h"
12 #include "serializeservicecontainer.h"
14 #include <boost/filesystem.hpp>
15 #include <boost/archive/text_oarchive.hpp>
16 #include <boost/archive/text_iarchive.hpp>
17 #include <boost/archive/archive_exception.hpp>
18 #include <boost/serialization/export.hpp>
19 #include <boost/serialization/shared_ptr.hpp>
25 * Default constructor with Logger object.
27 Serviceholder::Serviceholder(Logger::Ptr _log)
34 * Default destructor. While serializing and deserializing we use boost/shared_ptr, the resources are managed correctly.
36 Serviceholder::~Serviceholder()
42 * This function serializes all Service objects in Services and OldServices (where the update Timeout isn't expired) into a specified file.
43 * @return 0 if all is fine, -1 if output file could not be opened for reading or error while serializing.
45 int Serviceholder::serialize_services()
47 // Put Services and OldServices into Serviceholder.
48 SerializeServiceContainer::Ptr service_container(new SerializeServiceContainer);
50 BOOST_FOREACH(Service::Ptr &service, Services)
52 service_container->add_service(service);
55 int current_time = time(NULL);
57 BOOST_FOREACH(Service::Ptr &service, OldServices)
59 if ( ( service->get_last_updates()->front() + (service->get_update_interval()*60) ) >= current_time ) // UpdateInterval timeout of service isn't expired.
60 service_container->add_service(service);
63 // Serialize Serviceholder into file.
64 ofstream ofs(OBJECT_FILE);
67 SerializeServiceContainer* _service_container = service_container.get();
70 boost::archive::text_oarchive oa(ofs);
71 oa << _service_container;
73 catch( boost::archive::archive_exception e )
75 Log->print_exception_serialize(e.what());
84 Log->print_error_opening_rw(OBJECT_FILE);
88 Log->print_serialized_objects_success();
95 * This function de-serializes the SerializeServiceContainer (containing Services) from the object file.
96 * @return 0 if all is fine, -1 if object file couldn't be opened for reading or error while de-serializing.
98 int Serviceholder::deserialize_services()
100 // test if OBJECT_FILE exists
101 fs::path object_file = fs::system_complete(fs::path(OBJECT_FILE));
102 if ( !fs::exists(object_file) )
104 // There is no object file, possibly first program start, continue without recovering old Services' state.
105 Log->print_no_object_file(OBJECT_FILE);
109 ifstream ifs(OBJECT_FILE);
112 // deserialize SerializeServiceContainer
113 SerializeServiceContainer* _service_container;
116 boost::archive::text_iarchive ia(ifs);
117 ia >> _service_container;
119 catch( boost::archive::archive_exception e )
121 Log->print_exception_deserialize(e.what());
125 SerializeServiceContainer::Ptr service_container(_service_container);
128 // Get the list of old Services from de-serialized SerializeServiceContainer object.
129 list<Service::Ptr> _old_services = service_container->get_containing_services();
131 // Put all de-serialized Services into OldServices member and
132 // compare new Services (generated from config file and cmd) with old Services (de-serialized from object file)
133 // if identical Service was found, adopt the value from old Service to recover Services' state.
134 BOOST_FOREACH(Service::Ptr &old_service, _old_services)
136 OldServices.push_back(old_service);
137 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());
138 BOOST_FOREACH(Service::Ptr &service, Services)
140 if ( *service == *old_service )
142 service->set_last_updates(old_service->get_last_updates());
143 service->set_actual_ip(old_service->get_actual_ip());
144 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());
145 // We have adopted the values of the old_service. Just set lastupdated and timeout to 0, so this old_service wont be serialized.
146 old_service->set_update_interval(0);
150 Log->print_deserialized_objects_success();
154 Log->print_error_opening_r(OBJECT_FILE);
163 * Add service to internal service list.
164 * @param service Shared pointer to service object.
166 void Serviceholder::add_service(Service::Ptr service)
168 Services.push_back(service);
173 * Resets all shared Service pointers and clears the Services list.
175 void Serviceholder::delete_services()
177 BOOST_FOREACH( Service::Ptr &service, Services )
183 BOOST_FOREACH( Service::Ptr &service, OldServices )
192 * Getter for member Services
193 * @return List with shared Service pointers.
195 std::list<Service::Ptr> Serviceholder::get_services() const