PluginDeploymentEngine.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "PluginDeploymentEngine.hpp"
  14. #include <Shlwapi.h> // for path functions
  15. //#####################################################################################################
  16. //# NOTE: Plugins can no longer be shared and deployed as a component. To avoid version conflicts, #
  17. //# any component using a plugin (currently only ecl/attr servers) must deploy any necessary #
  18. //# plugins as part of its deployment. #
  19. //# This (pre-existing) class merely serves as a base class for components that need plugins. #
  20. //#####################################################################################################
  21. //---------------------------------------------------------------------------
  22. // CPluginDeploymentEngine
  23. //---------------------------------------------------------------------------
  24. CPluginDeploymentEngine::CPluginDeploymentEngine(IEnvDeploymentEngine& envDepEngine,
  25. IConstEnvironment& environment,
  26. IPropertyTree& process,
  27. const char* instanceType/*=NULL*/)
  28. : CDeploymentEngine(envDepEngine, environment, process, instanceType)
  29. {
  30. }
  31. //---------------------------------------------------------------------------
  32. // getPluginDirectory
  33. //
  34. // returns absolute path where plugins are to be deployed
  35. //---------------------------------------------------------------------------
  36. void CPluginDeploymentEngine::getPluginDirectory(const char* destPath, StringBuffer& sPluginDest) const
  37. {
  38. sPluginDest.clear().append(destPath);
  39. sPluginDest.replace('\\', '/');
  40. StringBuffer sPluginsDir; //relative path (from ECL server installation directory) for plugins
  41. m_process.getProp("@pluginsPath", sPluginsDir);
  42. if (sPluginsDir.length())
  43. {
  44. sPluginsDir.replace('\\', '/');
  45. sPluginsDir.replace('$', ':');
  46. if (! ::PathIsRelative(sPluginsDir.str()))
  47. throw MakeStringExceptionDirect(-1, "Plugins path for ECL server must be relative to its installation directory!");
  48. if (!strncmp(sPluginsDir.str(), "./", 2))
  49. sPluginsDir.remove(0, 2);
  50. sPluginDest.append(sPluginsDir);
  51. }
  52. const char* pchLast = sPluginDest.str() + sPluginDest.length() - 1;
  53. if (*pchLast != '/')
  54. sPluginDest.append('/');
  55. }
  56. //---------------------------------------------------------------------------
  57. // getDefaultPlugins
  58. //---------------------------------------------------------------------------
  59. void CPluginDeploymentEngine::getDefaultPlugins(StringArray& plugins,
  60. StringBuffer& sPluginsPath,
  61. const char* destDir) const
  62. {
  63. mmapStr2PairStrStr fileMap;
  64. CDeploymentEngine::createInstallFileMap(m_process, ".", fileMap);
  65. // Get install file list and sort out plugins
  66. mmapStr2PairStrStr::const_iterator i;
  67. mmapStr2PairStrStr::const_iterator iEnd = fileMap.end();
  68. for (i=fileMap.begin(); i != iEnd; i++)
  69. {
  70. const char* dest = (*i).first.c_str();
  71. const char* ext = ::PathFindExtension(dest);
  72. if (ext && *ext)
  73. {
  74. if (stricmp(ext, ".ecl")==0 || stricmp(ext, ".eclmod")==0)
  75. {
  76. if (plugins.find(dest) == NotFound)
  77. {
  78. plugins.append(dest);
  79. sPluginsPath.append(dest).append(';');
  80. }
  81. }
  82. else
  83. // Check that file matches plugin path .\plugins or ./plugins as specified in the release_eclserver file
  84. if (strlen(dest) > 2 && *dest == '.' && (*(dest+1)=='\\' || *(dest+1)=='/') &&
  85. strnicmp(dest+2, "plugins", sizeof("plugins")-1) == 0)
  86. {
  87. // Append plugin to files list - only care about dlls
  88. if (stricmp(ext, ".dll")==0 || stricmp(ext, ".so")==0)
  89. {
  90. StringBuffer path(destDir);
  91. path.append(::PathFindFileName( dest ));
  92. if (plugins.find(path.str()) == NotFound)
  93. {
  94. plugins.append(path.str());
  95. sPluginsPath.append(path.str()).append(';');
  96. }
  97. }
  98. }
  99. }
  100. }
  101. }
  102. //---------------------------------------------------------------------------
  103. // getPlugins
  104. //---------------------------------------------------------------------------
  105. void CPluginDeploymentEngine::getPlugins(StringArray& plugins,
  106. StringBuffer& sPluginsPath,
  107. const char* pluginDest) const
  108. {
  109. // Iterate through plugin references
  110. Owned<IPropertyTreeIterator> iter = m_process.getElements("PluginRef");
  111. ForEach(*iter)
  112. {
  113. // Lookup plugin process
  114. const char* pluginName = iter->query().queryProp("@process");
  115. IPropertyTree* pluginProcess = lookupProcess("PluginProcess", pluginName);
  116. if (!pluginProcess)
  117. throw MakeStringException(0, "Process %s references unknown plugin %s", m_name, pluginName);
  118. // Get plugin file list from the plugin process
  119. mmapStr2PairStrStr fileMap;
  120. CDeploymentEngine::createInstallFileMap(*pluginProcess, pluginDest, fileMap);
  121. mmapStr2PairStrStr::const_iterator i;
  122. mmapStr2PairStrStr::const_iterator iEnd = fileMap.end();
  123. for (i=fileMap.begin(); i != iEnd; i++)
  124. {
  125. const char* dest = (*i).first.c_str();
  126. const char* ext = ::PathFindExtension(dest);
  127. // Append plugin to files list - only care about dll/so
  128. if (ext && (stricmp(ext, ".dll")==0 || stricmp(ext, ".so")==0) &&
  129. plugins.find(dest) == NotFound)
  130. {
  131. plugins.append(dest);
  132. sPluginsPath.append(dest).append(';');
  133. }
  134. }
  135. }
  136. }
  137. //---------------------------------------------------------------------------
  138. // createInstallFileMap
  139. //---------------------------------------------------------------------------
  140. int CPluginDeploymentEngine::createInstallFileMap(IPropertyTree& node,
  141. const char* destPath,
  142. mmapStr2PairStrStr& fileMap) const
  143. {
  144. CDeploymentEngine::createInstallFileMap(node, destPath, fileMap);
  145. //get files for plugin references...
  146. //
  147. StringBuffer sPluginDest;
  148. getPluginDirectory(destPath, sPluginDest);//get absolute path where plugins are to be deployed
  149. //process plugin references for this eclserver process and add files for each service used by
  150. //each binding before adding files for this esp process
  151. Owned<IPropertyTreeIterator> iter = m_process.getElements("PluginRef");
  152. ForEach(*iter)
  153. {
  154. // Lookup plugin process
  155. const char* pluginName = iter->query().queryProp("@process");
  156. IPropertyTree* pluginProcess = lookupProcess("PluginProcess", pluginName);
  157. if (!pluginProcess)
  158. throw MakeStringException(0, "Process %s references unknown plugin %s", m_name, pluginName);
  159. // Get plugin file list from the plugin process
  160. CDeploymentEngine::createInstallFileMap(*pluginProcess, sPluginDest.str(), fileMap);
  161. }
  162. return fileMap.size();
  163. }