Skip to content
Commits on Source (4)
repo: 3959d33612ccaadc0d4d707227fbed09ac35e5fe
node: a2536c0d72deda960f2908e7bdcc56929837a0bf
branch: Orthanc-1.4.0
node: 218854b02a71c1ba79b446bf4273179b0098ae48
branch: Orthanc-1.4.1
latesttag: dcmtk-3.6.1
latesttagdistance: 354
changessincelatesttag: 396
latesttagdistance: 366
changessincelatesttag: 408
......@@ -54,7 +54,6 @@ include(${CMAKE_SOURCE_DIR}/Resources/CMake/OrthancFrameworkConfiguration.cmake)
set(ORTHANC_SERVER_SOURCES
OrthancServer/DatabaseWrapper.cpp
OrthancServer/DatabaseWrapperBase.cpp
OrthancServer/DicomInstanceOrigin.cpp
OrthancServer/DicomInstanceToStore.cpp
OrthancServer/ExportedResource.cpp
......
......@@ -99,5 +99,5 @@ namespace Orthanc
uint8_t green,
uint8_t blue,
uint8_t alpha);
};
}
}
......@@ -2,6 +2,13 @@ Pending changes in the mainline
===============================
Version 1.4.1 (2018-07-17)
==========================
* Fix deadlock in Lua scripting
* Simplification to the "DatabaseWrapper" class
Version 1.4.0 (2018-07-13)
==========================
......@@ -10,7 +17,7 @@ General
* New advanced job engine
* New configuration options:
- "ConcurrentJobs": Max number of jobs that are simultanously running
- "ConcurrentJobs": Max number of jobs that are simultaneously running
- "SynchronousCMove": Whether to run DICOM C-Move operations synchronously
- "JobsHistorySize": Max number of completed jobs that are kept in memory
* New metadata automatically computed at the instance level:
......
This diff is collapsed.
......@@ -37,7 +37,6 @@
#include "../Core/SQLite/Connection.h"
#include "../Core/SQLite/Transaction.h"
#include "DatabaseWrapperBase.h"
namespace Orthanc
{
......@@ -56,10 +55,19 @@ namespace Orthanc
private:
IDatabaseListener* listener_;
SQLite::Connection db_;
DatabaseWrapperBase base_;
Internals::SignalRemainingAncestor* signalRemainingAncestor_;
unsigned int version_;
void GetChangesInternal(std::list<ServerIndexChange>& target,
bool& done,
SQLite::Statement& s,
uint32_t maxResults);
void GetExportedResourcesInternal(std::list<ExportedResource>& target,
bool& done,
SQLite::Statement& s,
uint32_t maxResults);
void ClearTable(const std::string& tableName);
public:
......@@ -76,301 +84,197 @@ namespace Orthanc
virtual void SetListener(IDatabaseListener& listener);
virtual void SetGlobalProperty(GlobalProperty property,
const std::string& value)
virtual bool LookupParent(int64_t& parentId,
int64_t resourceId);
virtual std::string GetPublicId(int64_t resourceId);
virtual ResourceType GetResourceType(int64_t resourceId);
virtual void DeleteResource(int64_t id);
virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/,
bool& done /*out*/,
int64_t since,
uint32_t maxResults);
virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/);
virtual SQLite::ITransaction* StartTransaction()
{
base_.SetGlobalProperty(property, value);
return new SQLite::Transaction(db_);
}
virtual bool LookupGlobalProperty(std::string& target,
GlobalProperty property)
virtual void FlushToDisk()
{
return base_.LookupGlobalProperty(target, property);
db_.FlushToDisk();
}
virtual int64_t CreateResource(const std::string& publicId,
ResourceType type)
virtual bool HasFlushToDisk() const
{
return base_.CreateResource(publicId, type);
return true;
}
virtual bool LookupResource(int64_t& id,
ResourceType& type,
const std::string& publicId)
virtual void ClearChanges()
{
return base_.LookupResource(id, type, publicId);
ClearTable("Changes");
}
virtual bool LookupParent(int64_t& parentId,
int64_t resourceId);
virtual void ClearExportedResources()
{
ClearTable("ExportedResources");
}
virtual std::string GetPublicId(int64_t resourceId);
virtual void GetAllMetadata(std::map<MetadataType, std::string>& target,
int64_t id);
virtual ResourceType GetResourceType(int64_t resourceId);
virtual unsigned int GetDatabaseVersion()
{
return version_;
}
virtual void AttachChild(int64_t parent,
int64_t child)
virtual void Upgrade(unsigned int targetVersion,
IStorageArea& storageArea);
/**
* The methods declared below are for unit testing only!
**/
const char* GetErrorMessage() const
{
base_.AttachChild(parent, child);
return db_.GetErrorMessage();
}
virtual void DeleteResource(int64_t id);
void GetChildren(std::list<std::string>& childrenPublicIds,
int64_t id);
int64_t GetTableRecordCount(const std::string& table);
bool GetParentPublicId(std::string& target,
int64_t id);
/**
* Until Orthanc 1.4.0, the methods below were part of the
* "DatabaseWrapperBase" class, that is now placed in the
* graveyard.
**/
virtual void SetGlobalProperty(GlobalProperty property,
const std::string& value);
virtual bool LookupGlobalProperty(std::string& target,
GlobalProperty property);
virtual int64_t CreateResource(const std::string& publicId,
ResourceType type);
virtual bool LookupResource(int64_t& id,
ResourceType& type,
const std::string& publicId);
virtual void AttachChild(int64_t parent,
int64_t child);
virtual void SetMetadata(int64_t id,
MetadataType type,
const std::string& value)
{
base_.SetMetadata(id, type, value);
}
const std::string& value);
virtual void DeleteMetadata(int64_t id,
MetadataType type)
{
base_.DeleteMetadata(id, type);
}
MetadataType type);
virtual bool LookupMetadata(std::string& target,
int64_t id,
MetadataType type)
{
return base_.LookupMetadata(target, id, type);
}
MetadataType type);
virtual void ListAvailableMetadata(std::list<MetadataType>& target,
int64_t id)
{
base_.ListAvailableMetadata(target, id);
}
int64_t id);
virtual void AddAttachment(int64_t id,
const FileInfo& attachment)
{
base_.AddAttachment(id, attachment);
}
const FileInfo& attachment);
virtual void DeleteAttachment(int64_t id,
FileContentType attachment)
{
base_.DeleteAttachment(id, attachment);
}
FileContentType attachment);
virtual void ListAvailableAttachments(std::list<FileContentType>& target,
int64_t id)
{
return base_.ListAvailableAttachments(target, id);
}
int64_t id);
virtual bool LookupAttachment(FileInfo& attachment,
int64_t id,
FileContentType contentType)
{
return base_.LookupAttachment(attachment, id, contentType);
}
FileContentType contentType);
virtual void ClearMainDicomTags(int64_t id)
{
base_.ClearMainDicomTags(id);
}
virtual void ClearMainDicomTags(int64_t id);
virtual void SetMainDicomTag(int64_t id,
const DicomTag& tag,
const std::string& value)
{
base_.SetMainDicomTag(id, tag, value);
}
const std::string& value);
virtual void SetIdentifierTag(int64_t id,
const DicomTag& tag,
const std::string& value)
{
base_.SetIdentifierTag(id, tag, value);
}
const DicomTag& tag,
const std::string& value);
virtual void GetMainDicomTags(DicomMap& map,
int64_t id)
{
base_.GetMainDicomTags(map, id);
}
int64_t id);
virtual void GetChildrenPublicId(std::list<std::string>& target,
int64_t id)
{
base_.GetChildrenPublicId(target, id);
}
int64_t id);
virtual void GetChildrenInternalId(std::list<int64_t>& target,
int64_t id)
{
base_.GetChildrenInternalId(target, id);
}
int64_t id);
virtual void LogChange(int64_t internalId,
const ServerIndexChange& change)
{
base_.LogChange(internalId, change);
}
const ServerIndexChange& change);
virtual void GetChanges(std::list<ServerIndexChange>& target /*out*/,
bool& done /*out*/,
int64_t since,
uint32_t maxResults);
virtual void GetLastChange(std::list<ServerIndexChange>& target /*out*/);
virtual void LogExportedResource(const ExportedResource& resource)
{
base_.LogExportedResource(resource);
}
virtual void LogExportedResource(const ExportedResource& resource);
virtual void GetExportedResources(std::list<ExportedResource>& target /*out*/,
bool& done /*out*/,
int64_t since,
uint32_t maxResults)
{
base_.GetExportedResources(target, done, since, maxResults);
}
uint32_t maxResults);
virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/)
{
base_.GetLastExportedResource(target);
}
virtual void GetLastExportedResource(std::list<ExportedResource>& target /*out*/);
virtual uint64_t GetTotalCompressedSize()
{
return base_.GetTotalCompressedSize();
}
virtual uint64_t GetTotalCompressedSize();
virtual uint64_t GetTotalUncompressedSize()
{
return base_.GetTotalUncompressedSize();
}
virtual uint64_t GetTotalUncompressedSize();
virtual uint64_t GetResourceCount(ResourceType resourceType)
{
return base_.GetResourceCount(resourceType);
}
virtual uint64_t GetResourceCount(ResourceType resourceType);
virtual void GetAllInternalIds(std::list<int64_t>& target,
ResourceType resourceType)
{
base_.GetAllInternalIds(target, resourceType);
}
ResourceType resourceType);
virtual void GetAllPublicIds(std::list<std::string>& target,
ResourceType resourceType)
{
base_.GetAllPublicIds(target, resourceType);
}
ResourceType resourceType);
virtual void GetAllPublicIds(std::list<std::string>& target,
ResourceType resourceType,
size_t since,
size_t limit)
{
base_.GetAllPublicIds(target, resourceType, since, limit);
}
size_t limit);
virtual bool SelectPatientToRecycle(int64_t& internalId)
{
return base_.SelectPatientToRecycle(internalId);
}
virtual bool SelectPatientToRecycle(int64_t& internalId);
virtual bool SelectPatientToRecycle(int64_t& internalId,
int64_t patientIdToAvoid)
{
return base_.SelectPatientToRecycle(internalId, patientIdToAvoid);
}
int64_t patientIdToAvoid);
virtual bool IsProtectedPatient(int64_t internalId)
{
return base_.IsProtectedPatient(internalId);
}
virtual bool IsProtectedPatient(int64_t internalId);
virtual void SetProtectedPatient(int64_t internalId,
bool isProtected)
{
base_.SetProtectedPatient(internalId, isProtected);
}
bool isProtected);
virtual SQLite::ITransaction* StartTransaction()
{
return new SQLite::Transaction(db_);
}
virtual void FlushToDisk()
{
db_.FlushToDisk();
}
virtual bool HasFlushToDisk() const
{
return true;
}
virtual void ClearChanges()
{
ClearTable("Changes");
}
virtual void ClearExportedResources()
{
ClearTable("ExportedResources");
}
virtual bool IsExistingResource(int64_t internalId)
{
return base_.IsExistingResource(internalId);
}
virtual bool IsExistingResource(int64_t internalId);
virtual void LookupIdentifier(std::list<int64_t>& result,
ResourceType level,
const DicomTag& tag,
IdentifierConstraintType type,
const std::string& value)
{
base_.LookupIdentifier(result, level, tag, type, value);
}
const std::string& value);
virtual void LookupIdentifierRange(std::list<int64_t>& result,
ResourceType level,
const DicomTag& tag,
const std::string& start,
const std::string& end)
{
base_.LookupIdentifierRange(result, level, tag, start, end);
}
virtual void GetAllMetadata(std::map<MetadataType, std::string>& target,
int64_t id);
virtual unsigned int GetDatabaseVersion()
{
return version_;
}
virtual void Upgrade(unsigned int targetVersion,
IStorageArea& storageArea);
/**
* The methods declared below are for unit testing only!
**/
const char* GetErrorMessage() const
{
return db_.GetErrorMessage();
}
void GetChildren(std::list<std::string>& childrenPublicIds,
int64_t id);
int64_t GetTableRecordCount(const std::string& table);
bool GetParentPublicId(std::string& target,
int64_t id);
const std::string& end);
};
}
......@@ -49,8 +49,8 @@ namespace Orthanc
virtual void SignalStoredInstance(const std::string& publicId,
DicomInstanceToStore& instance,
const Json::Value& simplifiedTags) = 0;
const Json::Value& simplifiedTags) = 0;
virtual void SignalChange(const ServerIndexChange& change) = 0;
virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance,
......
......@@ -582,6 +582,9 @@ namespace Orthanc
lua_.RegisterFunction("RestApiPut", RestApiPut);
lua_.RegisterFunction("RestApiDelete", RestApiDelete);
lua_.RegisterFunction("GetOrthancConfiguration", GetOrthancConfiguration);
LOG(INFO) << "Initializing Lua for the event handler";
LoadGlobalConfiguration();
}
......
......@@ -33,8 +33,7 @@
#pragma once
#include "IServerListener.h"
#include "DicomInstanceToStore.h"
#include "ServerJobs/LuaJobManager.h"
#include "../Core/MultiThreading/SharedMessageQueue.h"
......@@ -44,7 +43,7 @@ namespace Orthanc
{
class ServerContext;
class LuaScripting : public IServerListener
class LuaScripting : public boost::noncopyable
{
private:
enum State
......@@ -88,6 +87,8 @@ namespace Orthanc
static void EventThread(LuaScripting* that);
void LoadGlobalConfiguration();
public:
class Lock : public boost::noncopyable
{
......@@ -116,19 +117,17 @@ namespace Orthanc
void Stop();
virtual void SignalStoredInstance(const std::string& publicId,
DicomInstanceToStore& instance,
const Json::Value& simplifiedTags);
void SignalStoredInstance(const std::string& publicId,
DicomInstanceToStore& instance,
const Json::Value& simplifiedTags);
virtual void SignalChange(const ServerIndexChange& change);
void SignalChange(const ServerIndexChange& change);
virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance,
const Json::Value& simplifiedTags);
bool FilterIncomingInstance(const DicomInstanceToStore& instance,
const Json::Value& simplifiedTags);
void Execute(const std::string& command);
void LoadGlobalConfiguration();
void SignalJobSubmitted(const std::string& jobId);
void SignalJobSuccess(const std::string& jobId);
......
......@@ -135,21 +135,21 @@ namespace Orthanc
void ServerContext::SignalJobSubmitted(const std::string& jobId)
{
haveJobsChanged_ = true;
lua_.SignalJobSubmitted(jobId);
mainLua_.SignalJobSubmitted(jobId);
}
void ServerContext::SignalJobSuccess(const std::string& jobId)
{
haveJobsChanged_ = true;
lua_.SignalJobSuccess(jobId);
mainLua_.SignalJobSuccess(jobId);
}
void ServerContext::SignalJobFailure(const std::string& jobId)
{
haveJobsChanged_ = true;
lua_.SignalJobFailure(jobId);
mainLua_.SignalJobFailure(jobId);
}
......@@ -225,7 +225,9 @@ namespace Orthanc
storeMD5_(true),
provider_(*this),
dicomCache_(provider_, DICOM_CACHE_SIZE),
lua_(*this),
mainLua_(*this),
filterLua_(*this),
luaListener_(*this),
#if ORTHANC_ENABLE_PLUGINS == 1
plugins_(NULL),
#endif
......@@ -234,7 +236,7 @@ namespace Orthanc
queryRetrieveArchive_(Configuration::GetGlobalUnsignedIntegerParameter("QueryRetrieveSize", 10)),
defaultLocalAet_(Configuration::GetGlobalStringParameter("DicomAet", "ORTHANC"))
{
listeners_.push_back(ServerListener(lua_, "Lua"));
listeners_.push_back(ServerListener(luaListener_, "Lua"));
SetupJobsEngine(unitTesting, loadJobsFromDatabase);
......@@ -699,7 +701,7 @@ namespace Orthanc
// TODO REFACTOR THIS
listeners_.clear();
listeners_.push_back(ServerListener(lua_, "Lua"));
listeners_.push_back(ServerListener(luaListener_, "Lua"));
listeners_.push_back(ServerListener(plugins, "plugin"));
}
......@@ -712,7 +714,7 @@ namespace Orthanc
// TODO REFACTOR THIS
listeners_.clear();
listeners_.push_back(ServerListener(lua_, "Lua"));
listeners_.push_back(ServerListener(luaListener_, "Lua"));
}
......
......@@ -63,6 +63,36 @@ namespace Orthanc
class ServerContext : private JobsRegistry::IObserver
{
private:
class LuaServerListener : public IServerListener
{
private:
ServerContext& context_;
public:
LuaServerListener(ServerContext& context) :
context_(context)
{
}
virtual void SignalStoredInstance(const std::string& publicId,
DicomInstanceToStore& instance,
const Json::Value& simplifiedTags)
{
context_.mainLua_.SignalStoredInstance(publicId, instance, simplifiedTags);
}
virtual void SignalChange(const ServerIndexChange& change)
{
context_.mainLua_.SignalChange(change);
}
virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance,
const Json::Value& simplified)
{
return context_.filterLua_.FilterIncomingInstance(instance, simplified);
}
};
class DicomCacheProvider : public ICachePageProvider
{
private:
......@@ -135,7 +165,9 @@ namespace Orthanc
MemoryCache dicomCache_;
JobsEngine jobsEngine_;
LuaScripting lua_;
LuaScripting mainLua_;
LuaScripting filterLua_;
LuaServerListener luaListener_;
#if ORTHANC_ENABLE_PLUGINS == 1
OrthancPlugins* plugins_;
......@@ -279,7 +311,7 @@ namespace Orthanc
LuaScripting& GetLuaScripting()
{
return lua_;
return mainLua_;
}
OrthancHttpHandler& GetHttpHandler()
......
......@@ -77,6 +77,8 @@ namespace Orthanc
GlobalProperty_FlushSleep = 2,
GlobalProperty_AnonymizationSequence = 3,
GlobalProperty_JobsRegistry = 5,
GlobalProperty_TotalCompressedSize = 6, // Reserved for Orthanc > 1.4.1
GlobalProperty_TotalUncompressedSize = 7, // Reserved for Orthanc > 1.4.1
// Reserved values for internal use by the database plugins
GlobalProperty_DatabasePatchLevel = 4,
......
......@@ -995,9 +995,6 @@ static bool ConfigureServerContext(IDatabaseWrapper& database,
context.GetIndex().SetMaximumStorageSize(0);
}
LOG(INFO) << "Initializing Lua for the event handler";
context.GetLuaScripting().LoadGlobalConfiguration();
context.GetJobsEngine().GetRegistry().SetMaxCompletedJobs
(Configuration::GetGlobalUnsignedIntegerParameter("JobsHistorySize", 10));
......
......@@ -3,7 +3,7 @@
#####################################################################
# Version of the build, should always be "mainline" except in release branches
set(ORTHANC_VERSION "1.4.0")
set(ORTHANC_VERSION "1.4.1")
# Version of the database schema. History:
# * Orthanc 0.1.0 -> Orthanc 0.3.0 = no versioning
......
......@@ -43,7 +43,7 @@
"Plugins" : [
],
// Maximum number of processing jobs that are simultanously running
// Maximum number of processing jobs that are simultaneously running
// at any given time. A value of "0" indicates to use all the
// available CPU logical cores. To emulate Orthanc <= 1.3.2, set
// this value to "1".
......
......@@ -85,6 +85,8 @@ if (ORTHANC_FRAMEWORK_SOURCE STREQUAL "hg" OR
set(ORTHANC_FRAMEWORK_MD5 "dac95bd6cf86fb19deaf4e612961f378")
elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.3.2")
set(ORTHANC_FRAMEWORK_MD5 "d0ccdf68e855d8224331f13774992750")
elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "1.4.0")
set(ORTHANC_FRAMEWORK_MD5 "81e15f34d97ac32bbd7d26e85698835a")
endif()
endif()
endif()
......