package.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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 "platform.h"
  14. #include "jprop.hpp"
  15. #include "jptree.hpp"
  16. #include "pkgimpl.hpp"
  17. #include "dadfs.hpp"
  18. #include "eclrtl.hpp"
  19. #include "jregexp.hpp"
  20. #include "dasds.hpp"
  21. #define SDS_LOCK_TIMEOUT (5*60*1000) // 5mins, 30s a bit short
  22. CPackageNode::CPackageNode(IPropertyTree *p)
  23. {
  24. if (p)
  25. node.set(p);
  26. else
  27. node.setown(createPTree("HpccPackages"));
  28. StringBuffer xml;
  29. toXML(node, xml);
  30. hash = rtlHash64Data(xml.length(), xml.str(), 9994410);
  31. }
  32. // Merge base package environment into mergedEnvironment
  33. void CPackageNode::mergeEnvironment(const CPackageNode *base)
  34. {
  35. Owned<IPropertyIterator> envIterator = base->mergedEnvironment->getIterator();
  36. ForEach(*envIterator)
  37. {
  38. const char *id = envIterator->getPropKey();
  39. const char *val = base->mergedEnvironment->queryProp(id);
  40. if (id && val && !mergedEnvironment->hasProp(id))
  41. mergedEnvironment->setProp(id, val);
  42. }
  43. }
  44. // Use local package and its bases to resolve superfile name list of subfiles via all supported resolvers
  45. ISimpleSuperFileEnquiry *CPackageNode::resolveSuperFile(const char *superFileName) const
  46. {
  47. // Order of resolution:
  48. // 1. SuperFiles named in local package
  49. // 2. SuperFiles named in bases
  50. // There is no dali or local case - a superfile that is resolved in dali must also resolve the subfiles there (and is all done in the resolveLFNusingDali method)
  51. if (superFileName && *superFileName && node)
  52. {
  53. if (*superFileName=='~')
  54. superFileName++;
  55. StringBuffer xpath;
  56. Owned<IPropertyTreeIterator> subFiles = lookupElements(makeSuperFileXPath(xpath, superFileName), "SubFile");
  57. if (subFiles)
  58. {
  59. Owned<CPackageSuperFileArray> result = new CPackageSuperFileArray(*subFiles);
  60. return result.getClear();
  61. }
  62. }
  63. return NULL;
  64. }
  65. // Load mergedEnvironment from local XML node
  66. void CPackageNode::loadEnvironment()
  67. {
  68. mergedEnvironment.setown(createProperties(true));
  69. Owned<IPropertyTreeIterator> envIterator = node->getElements("Environment");
  70. ForEach(*envIterator)
  71. {
  72. IPropertyTree &env = envIterator->query();
  73. const char *id = env.queryProp("@id");
  74. const char *val = env.queryProp("@value");
  75. if (!val)
  76. val = env.queryProp("@val"); // Historically we used val here - not sure why... other parts of package file used value
  77. if (id && val)
  78. mergedEnvironment->setProp(id, val);
  79. else
  80. {
  81. StringBuffer s;
  82. toXML(&env, s);
  83. throw MakeStringException(0, "PACKAGE_ERROR: Environment element missing id or value: %s", s.str());
  84. }
  85. }
  86. Owned<IAttributeIterator> attrs = node->getAttributes();
  87. for(attrs->first(); attrs->isValid(); attrs->next())
  88. {
  89. StringBuffer s("control:");
  90. s.append(attrs->queryName()+1); // queryName() has a leading @, hence the +1
  91. mergedEnvironment->setProp(s.str(), attrs->queryValue());
  92. }
  93. }
  94. CHpccPackage *createPackage(IPropertyTree *p)
  95. {
  96. return new CHpccPackage(p);
  97. }
  98. //================================================================================================
  99. // CPackageMap - an implementation of IPackageMap using a string map
  100. //================================================================================================
  101. //================================================================================================
  102. // CHpccPackageSet - an implementation of IHpccPackageSet
  103. //================================================================================================
  104. CHpccPackageSet::CHpccPackageSet(const char *_process) : process(_process)
  105. {
  106. Owned<IPropertyTree> ps = resolvePackageSetRegistry(process, true);
  107. if (ps)
  108. load(ps);
  109. }
  110. void CHpccPackageSet::load(IPropertyTree *xml)
  111. {
  112. Owned<IPropertyTreeIterator> it = xml->getElements("PackageMap[@active='1']"); //only active for now
  113. ForEach(*it)
  114. {
  115. IPropertyTree &tree = it->query();
  116. if (!tree.hasProp("@id"))
  117. continue;
  118. Owned<CHpccPackageMap> pm = new CHpccPackageMap(tree.queryProp("@id"), tree.queryProp("@querySet"), true);
  119. pm->load(tree.queryProp("@id"));
  120. packageMaps.append(*pm.getClear());
  121. }
  122. }
  123. const IHpccPackageMap *CHpccPackageSet::queryActiveMap(const char *queryset) const
  124. {
  125. ForEachItemIn(i, packageMaps)
  126. {
  127. CHpccPackageMap &pm = packageMaps.item(i);
  128. StringAttr &match = pm.querySet;
  129. if (!match.length())
  130. continue;
  131. if (isWildString(match))
  132. {
  133. if (WildMatch(queryset, match))
  134. return &pm;
  135. }
  136. else if (streq(queryset, match))
  137. return &pm;
  138. }
  139. return NULL;
  140. }
  141. extern WORKUNIT_API IHpccPackageSet *createPackageSet(const char *process)
  142. {
  143. return new CHpccPackageSet(process);
  144. }
  145. extern WORKUNIT_API IPropertyTree * getPackageMapById(const char * id, bool readonly)
  146. {
  147. StringBuffer xpath;
  148. xpath.append("/PackageMaps/PackageMap[@id=\"").append(id).append("\"]");
  149. Owned<IRemoteConnection> conn = querySDS().connect(xpath.str(), myProcessSession(), readonly ? RTM_LOCK_READ : RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
  150. if (!conn)
  151. return NULL;
  152. return conn->getRoot();
  153. }
  154. extern WORKUNIT_API IPropertyTree * getPackageSetById(const char * id, bool readonly)
  155. {
  156. StringBuffer xpath;
  157. xpath.append("/PackageSets/PackageSet[@id=\"").append(id).append("\"]");
  158. Owned<IRemoteConnection> conn = querySDS().connect(xpath.str(), myProcessSession(), readonly ? RTM_LOCK_READ : RTM_LOCK_WRITE, SDS_LOCK_TIMEOUT);
  159. if (!conn)
  160. return NULL;
  161. return conn->getRoot();
  162. }
  163. extern WORKUNIT_API IPropertyTree * resolvePackageSetRegistry(const char *process, bool readonly)
  164. {
  165. Owned<IRemoteConnection> globalLock = querySDS().connect("/PackageSets/", myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT);
  166. Owned<IPropertyTree> psroot = globalLock->getRoot();
  167. StringBuffer xpath;
  168. xpath.append("PackageSet[@process=\"").append(process).append("\"]");
  169. IPropertyTree *ps = psroot->queryPropTree(xpath);
  170. if (ps)
  171. return getPackageSetById(ps->queryProp("@id"), readonly);
  172. Owned<IPropertyTreeIterator> it = psroot->getElements("PackageSet[@process]");
  173. ForEach(*it)
  174. {
  175. const char *match = it->query().queryProp("@process");
  176. const char *id = it->query().queryProp("@id");
  177. if (id && isWildString(match) && WildMatch(process, match))
  178. return getPackageSetById(id, readonly);
  179. }
  180. return NULL;
  181. }