From d85c0bb88ae77d60f145aa42986b5e4d3649f883 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 18 Oct 2013 10:25:35 -0700 Subject: [PATCH] add a DELETE method to civetweb to delete assignment by UUID --- domain-server/src/DomainServer.cpp | 73 ++++++++++++++++++++++-------- domain-server/src/DomainServer.h | 1 + libraries/shared/src/NodeList.cpp | 24 +++++++--- libraries/shared/src/NodeList.h | 1 + 4 files changed, 74 insertions(+), 25 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 39c68d550f..18fa3cb2f8 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -46,6 +46,9 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { const struct mg_request_info* ri = mg_get_request_info(connection); const char RESPONSE_200[] = "HTTP/1.0 200 OK\r\n\r\n"; + const char RESPONSE_400[] = "HTTP/1.0 400 Bad Request\r\n\r\n"; + + const char ASSIGNMENT_URI[] = "/assignment"; if (strcmp(ri->uri, "/assignment") == 0 && strcmp(ri->request_method, "POST") == 0) { // return a 200 @@ -120,6 +123,35 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) { // we've processed this request return 1; + } else if (strcmp(ri->request_method, "DELETE") == 0) { + // this is a DELETE request + + // check if it is for an assignment + if (memcmp(ri->uri, ASSIGNMENT_URI, sizeof(ASSIGNMENT_URI) - sizeof('\0')) == 0) { + // pull the UUID from the url + QUuid deleteUUID = QUuid(QString(ri->uri + strlen(ASSIGNMENT_URI) + sizeof('/'))); + + if (!deleteUUID.isNull()) { + Node *nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID); + + if (nodeToKill) { + // start with a 200 response + mg_printf(connection, "%s", RESPONSE_200); + + // we have a valid UUID and node - kill the node that has this assignment + NodeList::getInstance()->killNode(nodeToKill); + + // successfully processed request + return 1; + } + } + } + + // request not processed - bad request + mg_printf(connection, "%s", RESPONSE_400); + + // this was processed by civetweb + return 1; } else { // have mongoose process this request from the document_root return 0; @@ -160,6 +192,27 @@ void DomainServer::civetwebUploadHandler(struct mg_connection *connection, const domainServerInstance->_assignmentQueueMutex.unlock(); } +void DomainServer::addDeletedAssignmentBackToQueue(Assignment* deletedAssignment) { + qDebug() << "Adding assignment" << *deletedAssignment << " back to queue.\n"; + + // find this assignment in the static file + for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) { + if (_staticAssignments[i].getUUID() == deletedAssignment->getUUID()) { + // reset the UUID on the static assignment + _staticAssignments[i].resetUUID(); + + // put this assignment back in the queue so it goes out + _assignmentQueueMutex.lock(); + _assignmentQueue.push_back(&_staticAssignments[i]); + _assignmentQueueMutex.unlock(); + + } else if (_staticAssignments[i].getUUID().isNull()) { + // we are at the blank part of the static assignments - break out + break; + } + } +} + void DomainServer::nodeAdded(Node* node) { } @@ -169,26 +222,8 @@ void DomainServer::nodeKilled(Node* node) { if (node->getLinkedData()) { Assignment* nodeAssignment = (Assignment*) node->getLinkedData(); - qDebug() << "Adding assignment" << *nodeAssignment << " back to queue.\n"; - - // find this assignment in the static file - for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) { - if (_staticAssignments[i].getUUID() == nodeAssignment->getUUID()) { - // reset the UUID on the static assignment - _staticAssignments[i].resetUUID(); - - // put this assignment back in the queue so it goes out - _assignmentQueueMutex.lock(); - _assignmentQueue.push_back(&_staticAssignments[i]); - _assignmentQueueMutex.unlock(); - - } else if (_staticAssignments[i].getUUID().isNull()) { - // we are at the blank part of the static assignments - break out - break; - } - } + addDeletedAssignmentBackToQueue(nodeAssignment); } - } unsigned char* DomainServer::addNodeToBroadcastPacket(unsigned char* currentPosition, Node* nodeToAdd) { diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 205d9e8f6e..78e1f06587 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -47,6 +47,7 @@ private: void removeAssignmentFromQueue(Assignment* removableAssignment); bool checkInWithUUIDMatchesExistingNode(sockaddr* nodePublicSocket, sockaddr* nodeLocalSocket, const QUuid& checkInUUI); void possiblyAddStaticAssignmentsBackToQueueAfterRestart(timeval* startTime); + void addDeletedAssignmentBackToQueue(Assignment* deletedAssignment); void cleanup(); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index e067c7afa9..a7a6dac5aa 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -715,6 +715,22 @@ Node* NodeList::soloNodeOfType(char nodeType) { return NULL; } +void NodeList::killNode(Node* node, bool mustLockNode) { + if (mustLockNode) { + node->lock(); + } + + qDebug() << "Killed " << *node << "\n"; + + notifyHooksOfKilledNode(&*node); + + node->setAlive(false); + + if (mustLockNode) { + node->unlock(); + } +} + void* removeSilentNodes(void *args) { NodeList* nodeList = (NodeList*) args; uint64_t checkTimeUsecs = 0; @@ -728,12 +744,8 @@ void* removeSilentNodes(void *args) { node->lock(); if ((usecTimestampNow() - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) { - - qDebug() << "Killed " << *node << "\n"; - - nodeList->notifyHooksOfKilledNode(&*node); - - node->setAlive(false); + // kill this node, don't lock - we already did it + nodeList->killNode(&(*node), false); } node->unlock(); diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index f98ae7070c..5361f12ca6 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -113,6 +113,7 @@ public: Node* nodeWithUUID(const QUuid& nodeUUID); Node* addOrUpdateNode(const QUuid& uuid, char nodeType, sockaddr* publicSocket, sockaddr* localSocket); + void killNode(Node* node, bool mustLockNode = true); void processNodeData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); void processBulkNodeData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes);