bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName, const String& config, const Array::Ptr& errors) { if (!ConfigPackageUtility::PackageExists("_api")) { ConfigPackageUtility::CreatePackage("_api"); String stage = ConfigPackageUtility::CreateStage("_api"); ConfigPackageUtility::ActivateStage("_api", stage); } String path = GetObjectConfigPath(type, fullName); Utility::MkDirP(Utility::DirName(path), 0700); if (Utility::PathExists(path)) { errors->Add("Configuration file '" + path + "' already exists."); return false; } std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc); fp << config; fp.close(); Expression *expr = ConfigCompiler::CompileFile(path, String(), "_api"); try { ActivationScope ascope; ScriptFrame frame; expr->Evaluate(frame); delete expr; expr = NULL; WorkQueue upq; std::vector<ConfigItem::Ptr> newItems; if (!ConfigItem::CommitItems(ascope.GetContext(), upq, newItems) || !ConfigItem::ActivateItems(upq, newItems, true)) { if (errors) { if (unlink(path.CStr()) < 0 && errno != ENOENT) { BOOST_THROW_EXCEPTION(posix_error() << boost::errinfo_api_function("unlink") << boost::errinfo_errno(errno) << boost::errinfo_file_name(path)); } for (const boost::exception_ptr& ex : upq.GetExceptions()) { errors->Add(DiagnosticInformation(ex)); } } return false; } ApiListener::UpdateObjectAuthority(); } catch (const std::exception& ex) { delete expr; if (unlink(path.CStr()) < 0 && errno != ENOENT) { BOOST_THROW_EXCEPTION(posix_error() << boost::errinfo_api_function("unlink") << boost::errinfo_errno(errno) << boost::errinfo_file_name(path)); } if (errors) errors->Add(DiagnosticInformation(ex)); return false; } return true; }
bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& fullName, const String& config, const Array::Ptr& errors, const Array::Ptr& diagnosticInformation) { { boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex()); if (!ConfigPackageUtility::PackageExists("_api")) { ConfigPackageUtility::CreatePackage("_api"); String stage = ConfigPackageUtility::CreateStage("_api"); ConfigPackageUtility::ActivateStage("_api", stage); } } ConfigItem::Ptr item = ConfigItem::GetByTypeAndName(type, fullName); if (item) { errors->Add("Object '" + fullName + "' already exists."); return false; } String path = GetObjectConfigPath(type, fullName); Utility::MkDirP(Utility::DirName(path), 0700); if (Utility::PathExists(path)) { errors->Add("Cannot create object '" + fullName + "'. Configuration file '" + path + "' already exists."); return false; } std::ofstream fp(path.CStr(), std::ofstream::out | std::ostream::trunc); fp << config; fp.close(); std::unique_ptr<Expression> expr = ConfigCompiler::CompileFile(path, String(), "_api"); try { ActivationScope ascope; ScriptFrame frame(true); expr->Evaluate(frame); expr.reset(); WorkQueue upq; upq.SetName("ConfigObjectUtility::CreateObject"); std::vector<ConfigItem::Ptr> newItems; /* Disable logging for object creation, but do so ourselves later on. */ if (!ConfigItem::CommitItems(ascope.GetContext(), upq, newItems, true) || !ConfigItem::ActivateItems(upq, newItems, true, true)) { if (errors) { if (unlink(path.CStr()) < 0 && errno != ENOENT) { BOOST_THROW_EXCEPTION(posix_error() << boost::errinfo_api_function("unlink") << boost::errinfo_errno(errno) << boost::errinfo_file_name(path)); } for (const boost::exception_ptr& ex : upq.GetExceptions()) { errors->Add(DiagnosticInformation(ex, false)); if (diagnosticInformation) diagnosticInformation->Add(DiagnosticInformation(ex)); } } return false; } ApiListener::UpdateObjectAuthority(); Log(LogInformation, "ConfigObjectUtility") << "Created and activated object '" << fullName << "' of type '" << type->GetName() << "'."; } catch (const std::exception& ex) { if (unlink(path.CStr()) < 0 && errno != ENOENT) { BOOST_THROW_EXCEPTION(posix_error() << boost::errinfo_api_function("unlink") << boost::errinfo_errno(errno) << boost::errinfo_file_name(path)); } if (errors) errors->Add(DiagnosticInformation(ex, false)); if (diagnosticInformation) diagnosticInformation->Add(DiagnosticInformation(ex)); return false; } return true; }