PageRenderTime 29ms CodeModel.GetById 9ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/vmManager.cpp

https://github.com/deltaforge/nebu-app-framework-cpp
C++ | 209 lines | 175 code | 31 blank | 3 comment | 22 complexity | 115352f336dee86c1dd443b1bb313f11 MD5 | raw file
  1
  2#include "nebu-app-framework/vmManager.h"
  3
  4#include "nebu/util/exceptions.h"
  5
  6#include "log4cxx/logger.h"
  7
  8#include <set>
  9
 10// Using declarations - standard library
 11using std::list;
 12using std::make_shared;
 13using std::set;
 14using std::shared_ptr;
 15using std::string;
 16using std::unordered_map;
 17using std::vector;
 18// Using declarations - nebu-common
 19using nebu::common::NebuServerException;
 20using nebu::common::VirtualMachine;
 21using nebu::common::VMStatus;
 22
 23static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("nebu.app.framework.VMManager"));
 24
 25#define FOREACH_EVENTHANDLER(itName) \
 26	for (list<shared_ptr<VMEventHandler>>::iterator itName = this->vmEventHandlers.begin(); \
 27		 itName != this->vmEventHandlers.end(); \
 28		 itName++)
 29
 30namespace nebu
 31{
 32	namespace app
 33	{
 34		namespace framework
 35		{
 36
 37			bool VMManager::refreshVMList()
 38			{
 39				vector<string> vmIDs;
 40				try {
 41					vmIDs = this->appVirtRequest->getVirtualMachineIDs();
 42				} catch (NebuServerException &ex) {
 43					LOG4CXX_WARN(logger, "Could not refresh VM list\n" + ex.what());
 44					return false;
 45				}
 46
 47				vector<string> vmIDsFiltered(vmIDs);
 48				bool succes = true;
 49
 50				succes &= this->addNewVMs(vmIDsFiltered);
 51				succes &= this->updateVMs(vmIDsFiltered);
 52				this->removeVMs(vmIDs);
 53
 54				return succes;
 55			}
 56
 57			bool VMManager::addNewVMs(vector<string> &retrievedVMIds)
 58			{
 59				bool succes = true;
 60				for (vector<string>::iterator it = retrievedVMIds.begin();
 61					 it != retrievedVMIds.end();
 62					 )
 63				{
 64					if (this->vmList.find(*it) == this->vmList.end()) {
 65						try {
 66							shared_ptr<VirtualMachine> newVM = make_shared<VirtualMachine>(
 67									this->appVirtRequest->getVirtualMachine(*it));
 68							LOG4CXX_INFO(logger, "Detected new VM with hostname '" + newVM->getHostname() +
 69									"' (id: " + newVM->getUUID() + ")");
 70							LOG4CXX_DEBUG(logger, "\tHost: " << newVM->getPhysicalHostID() <<
 71									", store: " << newVM->getPhysicalStoreID() << ", status: " <<
 72									static_cast<unsigned int>(newVM->getStatus()));
 73							this->addVM(newVM);
 74						} catch (NebuServerException &ex) {
 75							LOG4CXX_WARN(logger, "Missing information on a new vm\n" + ex.what());
 76							succes = false;
 77						}
 78
 79						retrievedVMIds.erase(it);
 80					} else {
 81						it++;
 82					}
 83				}
 84				return succes;
 85			}
 86
 87			bool VMManager::updateVMs(vector<string> &filteredVMIds)
 88			{
 89				bool succes = true;
 90				for (vector<string>::iterator it = filteredVMIds.begin();
 91					 it != filteredVMIds.end();
 92					 it++)
 93				{
 94					shared_ptr<VirtualMachine> vm = this->vmList[*it];
 95					try {
 96						VirtualMachine updatedVM = this->appVirtRequest->getVirtualMachine(*it);
 97						if (vm->getStatus() != updatedVM.getStatus()) {
 98							LOG4CXX_INFO(logger, "Detected change in VM with hostname '" << vm->getHostname() <<
 99									"' (id: " << vm->getUUID() << ")");
100							LOG4CXX_DEBUG(logger, "\tStatus from " << static_cast<unsigned int>(vm->getStatus()) <<
101									" to " << static_cast<unsigned int>(updatedVM.getStatus()));
102
103							this->updateVM(vm, updatedVM);
104						}
105					} catch (NebuServerException &ex) {
106						// TODO: Decide: should the VM status be set to UNKNOWN?
107						LOG4CXX_WARN(logger, "Missing information for a VM update\n" + ex.what());
108						succes = false;
109					}
110				}
111				return succes;
112			}
113
114			void VMManager::removeVMs(vector<string> &retrievedVMIds)
115			{
116				vector<shared_ptr<VirtualMachine>> knownVMs = this->getVMs();
117				set<string> vmIDSet(retrievedVMIds.begin(), retrievedVMIds.end());
118
119				for (vector<shared_ptr<VirtualMachine>>::iterator it = knownVMs.begin();
120					 it != knownVMs.end();
121					 it++)
122				{
123					if (vmIDSet.find((*it)->getUUID()) == vmIDSet.end()) {
124						this->removeVM(*it);
125					}
126				}
127			}
128
129			vector<shared_ptr<VirtualMachine>> VMManager::getVMs() const
130			{
131				vector<shared_ptr<VirtualMachine>> res;
132				for (unordered_map<string, shared_ptr<VirtualMachine>>::const_iterator it = this->vmList.begin();
133						it != this->vmList.end();
134						it++)
135				{
136					res.push_back(it->second);
137				}
138				return res;
139			}
140
141			shared_ptr<VirtualMachine> VMManager::getVM(const string &uuid) const
142			{
143				if (this->hasVM(uuid)) {
144					return this->vmList.at(uuid);
145				} else {
146					return shared_ptr<VirtualMachine>();
147				}
148			}
149
150			void VMManager::addVM(shared_ptr<VirtualMachine> vm)
151			{
152				this->vmList[vm->getUUID()] = vm;
153
154				FOREACH_EVENTHANDLER(ev)
155				{
156					ev->get()->newVMAdded(vm);
157				}
158			}
159
160			void VMManager::updateVM(shared_ptr<VirtualMachine> vm, const VirtualMachine &updated)
161			{
162				if (vm->getStatus() != updated.getStatus()) {
163					vm->setStatus(updated.getStatus());
164
165					VMEvent event;
166					switch (vm->getStatus())
167					{
168					case VMStatus::ON:
169						event = VMEvent::POWERED_ON;
170						break;
171					case VMStatus::OFF:
172						event = VMEvent::POWERED_OFF;
173						break;
174					case VMStatus::UNKNOWN:
175						event = VMEvent::UNKNOWN;
176						break;
177					}
178
179					FOREACH_EVENTHANDLER(ev)
180					{
181						ev->get()->existingVMChanged(vm, event);
182					}
183				}
184			}
185
186			void VMManager::removeVM(shared_ptr<VirtualMachine> vm)
187			{
188				this->vmList.erase(vm->getUUID());
189
190				FOREACH_EVENTHANDLER(ev)
191				{
192					ev->get()->oldVMRemoved(*vm);
193				}
194			}
195
196			bool VMManager::hasVM(const string &uuid) const
197			{
198				return (this->vmList.count(uuid) > 0);
199			}
200
201			void VMManager::registerVMEventHandler(shared_ptr<VMEventHandler> eventHandler)
202			{
203				this->vmEventHandlers.push_back(eventHandler);
204			}
205
206		}
207	}
208}
209