Browse Source

[2862] Some error handling in the segment update

Michal 'vorner' Vaner 11 years ago
parent
commit
7276a2eddf

+ 16 - 0
src/bin/auth/auth_messages.mes

@@ -145,6 +145,22 @@ reconfigure, and has now started this process.
 The thread for maintaining data source clients has finished reconfiguring
 The thread for maintaining data source clients has finished reconfiguring
 the data source clients, and is now running with the new configuration.
 the data source clients, and is now running with the new configuration.
 
 
+% AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_BAD_CLASS invalid RRclass %1 at segment update
+A memory segment update message was sent to the authoritative server. But the
+class contained there is no valid class, so the update is dropped. This is
+likely a bug in the code.
+
+% AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_ERROR error updating the memory segment: %1
+The authoritative server tried to update the memory segment. But the update
+failed. The update is dropped. This is likely a bug in the code.
+
+% AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_UNKNOWN_CLASS unknown class %1 at segment update
+A memory segment update message was sent to the authoritative server. The class
+name for which the update should happen is valid, but no client lists are
+configured for that class. The update is dropped. This may be caused by a bug
+in the code or by a temporary inconsistancy between the memory manager and the
+authoritative server after change of configuration.
+
 % AUTH_DATASRC_CLIENTS_BUILDER_STARTED data source builder thread started
 % AUTH_DATASRC_CLIENTS_BUILDER_STARTED data source builder thread started
 A separate thread for maintaining data source clients has been started.
 A separate thread for maintaining data source clients has been started.
 
 

+ 27 - 14
src/bin/auth/datasrc_clients_mgr.h

@@ -627,21 +627,34 @@ private:
     }
     }
 
 
     void doSegmentUpdate(const isc::data::ConstElementPtr& arg) {
     void doSegmentUpdate(const isc::data::ConstElementPtr& arg) {
-        // TODO: Error handling. Invalid RRClass, non-existing stuff, exceptions
-        const isc::dns::RRClass
-            rrclass(arg->get("data-source-class")->stringValue());
-        const std::string& name(arg->get("data-source-name")->stringValue());
-        const isc::data::ConstElementPtr& segment_params =
-            arg->get("segment-params");
-        typename MutexType::Locker locker(*map_mutex_);
-        const boost::shared_ptr<isc::datasrc::ConfigurableClientList>& list =
-            (**clients_map_)[rrclass];
-        if (!list) {
-            // TODO: Log error
-            return;
+        try {
+            const isc::dns::RRClass
+                rrclass(arg->get("data-source-class")->stringValue());
+            const std::string&
+                name(arg->get("data-source-name")->stringValue());
+            const isc::data::ConstElementPtr& segment_params =
+                arg->get("segment-params");
+            typename MutexType::Locker locker(*map_mutex_);
+            const boost::shared_ptr<isc::datasrc::ConfigurableClientList>&
+                list = (**clients_map_)[rrclass];
+            if (!list) {
+                LOG_ERROR(auth_logger,
+                          AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_UNKNOWN_CLASS)
+                    .arg(rrclass);
+                return;
+            }
+            list->resetMemorySegment(name,
+                isc::datasrc::memory::ZoneTableSegment::READ_ONLY,
+                segment_params);
+        } catch (const isc::dns::InvalidRRClass& irce) {
+            LOG_ERROR(auth_logger,
+                      AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_BAD_CLASS)
+                .arg(arg->get("data-source-class"));
+        } catch (const isc::Exception& e) {
+            LOG_ERROR(auth_logger,
+                      AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_ERROR)
+                .arg(e.what());
         }
         }
-        list->resetMemorySegment(name,
-            isc::datasrc::memory::ZoneTableSegment::READ_ONLY, segment_params);
     }
     }
 
 
     void doLoadZone(const isc::data::ConstElementPtr& arg);
     void doLoadZone(const isc::data::ConstElementPtr& arg);

+ 29 - 0
src/bin/auth/tests/datasrc_clients_builder_unittest.cc

@@ -703,6 +703,35 @@ TEST_F(DataSrcClientsBuilderTest,
                                   FinishedCallback()));
                                   FinishedCallback()));
     // The segment is now used.
     // The segment is now used.
     EXPECT_EQ(SEGMENT_INUSE, list->getStatus()[0].getSegmentState());
     EXPECT_EQ(SEGMENT_INUSE, list->getStatus()[0].getSegmentState());
+
+    // Some invalid inputs (wrong class, different name of data source, etc).
+
+    // Copy the confing and modify
+    const ElementPtr bad_name = Element::fromJSON(command_args->toWire());
+    // Set bad name
+    bad_name->set("data-source-name", Element::create("bad"));
+    // Nothing breaks
+    builder.handleCommand(Command(SEGMENT_INFO_UPDATE, bad_name,
+                                  FinishedCallback()));
+
+    // Another copy with wrong class
+    const ElementPtr bad_class = Element::fromJSON(command_args->toWire());
+    // Set bad class
+    bad_class->set("data-source-class", Element::create("bad"));
+    // Nothing breaks
+    builder.handleCommand(Command(SEGMENT_INFO_UPDATE, bad_class,
+                                  FinishedCallback()));
+
+    // Class CH is valid, but not present.
+    bad_class->set("data-source-class", Element::create("CH"));
+    // Nothing breaks
+    builder.handleCommand(Command(SEGMENT_INFO_UPDATE, bad_class,
+                                  FinishedCallback()));
+
+    // And break the segment params
+    const ElementPtr bad_params = Element::fromJSON(command_args->toWire());
+    bad_params->set("segment-params",
+                    Element::fromJSON("{\"mapped-file\": \"/bad/file\"}"));
 }
 }
 
 
 } // unnamed namespace
 } // unnamed namespace