PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/condor-7.9.0/src/classad_support/remoteQuery.cpp

#
C++ | 306 lines | 224 code | 49 blank | 33 comment | 45 complexity | 41f4f807e7d04008400683cca84cc7bd MD5 | raw file
Possible License(s): Apache-2.0
  1. /***************************************************************
  2. *
  3. * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
  4. * University of Wisconsin-Madison, WI.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License"); you
  7. * may not use this file except in compliance with the License. You may
  8. * obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. ***************************************************************/
  19. #include "condor_common.h"
  20. #include "classad/common.h"
  21. #include "collectionServer.h"
  22. #include "remoteQuery.h"
  23. using namespace std;
  24. namespace classad {
  25. // --- remote collection query implementation begins ---
  26. RemoteCollectionQuery::
  27. RemoteCollectionQuery( )
  28. {
  29. wantResults = true;
  30. wantPostlude= false;
  31. accumulate = false;
  32. itr = results.end( );
  33. }
  34. RemoteCollectionQuery::
  35. ~RemoteCollectionQuery( )
  36. {
  37. ClearResults( );
  38. }
  39. bool RemoteCollectionQuery::
  40. Connect( const string &serverAddr, int port )
  41. {
  42. serverSock.close( );
  43. serverSock.encode( );
  44. if( !serverSock.connect( (char*)serverAddr.c_str( ), port ) ||
  45. !serverSock.put((int)ClassAdCollectionInterface::ClassAdCollOp_Connect)
  46. || !serverSock.end_of_message() ){
  47. CondorErrno = ERR_CONNECT_FAILED;
  48. CondorErrMsg = "failed to connect to collection server";
  49. return( false );
  50. }
  51. return( true );
  52. }
  53. void RemoteCollectionQuery::
  54. Disconnect( )
  55. {
  56. serverSock.encode( );
  57. serverSock.put( (int)ClassAdCollectionInterface::ClassAdCollOp_Disconnect );
  58. serverSock.end_of_message( );
  59. serverSock.close( );
  60. }
  61. void RemoteCollectionQuery::
  62. SetProjectionAttrs( const vector<string> &attrs )
  63. {
  64. vector<string>::const_iterator itr;
  65. projectionAttrs.clear( );
  66. for( itr = attrs.begin( ); itr != attrs.end( ); itr++ ) {
  67. projectionAttrs.push_back( *itr );
  68. }
  69. }
  70. void RemoteCollectionQuery::
  71. GetProjectionAttrs( vector<string> &attrs ) const
  72. {
  73. vector<string>::const_iterator itr;
  74. attrs.clear( );
  75. for( itr = projectionAttrs.begin( ); itr != projectionAttrs.end( ); itr++ ){
  76. attrs.push_back( *itr );
  77. }
  78. }
  79. bool RemoteCollectionQuery::
  80. PostQuery( const string &viewName, ExprTree *constraint )
  81. {
  82. vector<string>::iterator sitr;
  83. vector<ExprTree*> projAttrs;
  84. ExprTree *tree;
  85. Value val;
  86. ClassAd query;
  87. // first construct the query ...
  88. ClearResults( );
  89. query.InsertAttr( "WantResults", wantResults );
  90. query.InsertAttr( "WantPostlude", wantPostlude );
  91. query.InsertAttr( "ViewName", viewName );
  92. if( constraint ) {
  93. query.Insert( ATTR_REQUIREMENTS, constraint );
  94. } else {
  95. query.InsertAttr( ATTR_REQUIREMENTS, true );
  96. }
  97. for( sitr=projectionAttrs.begin( ); sitr!=projectionAttrs.end( ); sitr++ ) {
  98. val.SetStringValue( *sitr );
  99. if( !(tree = Literal::MakeLiteral( val ) ) ) {
  100. vector<ExprTree*>::iterator pitr;
  101. CondorErrno = ERR_MEM_ALLOC_FAILED;
  102. CondorErrMsg = "";
  103. for( pitr=projAttrs.begin( ); pitr!=projAttrs.end( ); pitr++ ) {
  104. delete *pitr;
  105. }
  106. return( false );
  107. }
  108. projAttrs.push_back( tree );
  109. }
  110. query.Insert( "ProjectionAttrs", ExprList::MakeExprList( projAttrs ) );
  111. // send the query to the server
  112. ClassAdUnParser unp;
  113. string buffer;
  114. serverSock.encode( );
  115. unp.Unparse( buffer, &query );
  116. if(!serverSock.put((int)ClassAdCollectionInterface::ClassAdCollOp_QueryView)
  117. || !serverSock.put((char*)buffer.c_str( )) || !serverSock.end_of_message( ) ) {
  118. CondorErrno = ERR_COMMUNICATION_ERROR;
  119. CondorErrMsg = "failed to send query to collection server";
  120. return( false );
  121. }
  122. // get ready to receive response
  123. finished = false;
  124. itr = results.begin( );
  125. return( true );
  126. }
  127. void RemoteCollectionQuery::
  128. ClearResults( )
  129. {
  130. for( itr = results.begin( ); itr != results.end( ); itr++ ) {
  131. delete itr->second;
  132. }
  133. results.clear( );
  134. postlude.Clear( );
  135. finished = false;
  136. }
  137. bool RemoteCollectionQuery::
  138. ToFirst( )
  139. {
  140. if( !accumulate ) return( false );
  141. itr = results.begin( );
  142. return( true );
  143. }
  144. bool RemoteCollectionQuery::
  145. IsAtFirst( ) const
  146. {
  147. if( !accumulate ) return( false );
  148. return( results.begin( ) == itr );
  149. }
  150. bool RemoteCollectionQuery::
  151. Next( string &key, ClassAd *& ad )
  152. {
  153. // if we're iterating over already downloaded results ...
  154. if( itr != results.end( ) ) {
  155. itr++;
  156. key = itr->first;
  157. ad = itr->second;
  158. return( true );
  159. }
  160. // itr==results.end( ); are we already done?
  161. if( finished ) {
  162. return( false ); // done
  163. }
  164. // not done; need to download next item
  165. string buffer;
  166. char *tmp=NULL;
  167. serverSock.decode( );
  168. if( !serverSock.get( tmp ) ) {
  169. if( tmp ) free( tmp );
  170. CondorErrno = ERR_COMMUNICATION_ERROR;
  171. CondorErrMsg = "failed to retrieve result from collection server";
  172. return( false );
  173. }
  174. buffer = tmp;
  175. free( tmp );
  176. // is server done with sending results?
  177. if( strcmp( (char*)buffer.c_str( ), "<done>" ) == 0 ) {
  178. finished = true;
  179. // get postlude if necessary
  180. tmp = NULL;
  181. if( wantPostlude ) {
  182. if( !serverSock.get( tmp ) || !serverSock.end_of_message( ) ) {
  183. if( tmp ) free( tmp );
  184. CondorErrno = ERR_COMMUNICATION_ERROR;
  185. CondorErrMsg = "failed to receive query postlude from server";
  186. return( false );
  187. }
  188. buffer = tmp;
  189. free( tmp );
  190. postlude.Clear( );
  191. if( !parser.ParseClassAd( buffer, postlude ) ) {
  192. CondorErrMsg += "; failed to parse query postlude";
  193. return( false );
  194. }
  195. } else if( !serverSock.end_of_message( ) ) {
  196. // no postlude
  197. CondorErrno = ERR_COMMUNICATION_ERROR;
  198. CondorErrMsg = "failed to receive end_of_message() from server";
  199. return( false );
  200. }
  201. // done with results, so return false
  202. return( false );
  203. }
  204. // not done; buffer contains an ad
  205. ClassAd *tmpAd=NULL;
  206. if( !( tmpAd = parser.ParseClassAd( buffer ) ) ) {
  207. CondorErrMsg += "; failed to parse query result";
  208. return( false );
  209. }
  210. tmpAd->EvaluateAttrString( ATTR_KEY, key );
  211. ad = (ClassAd*)tmpAd->Remove( ATTR_AD );
  212. delete tmpAd;
  213. // if accumulating, add <key,ad> to the results list
  214. if( accumulate ) {
  215. results.push_back( make_pair( key, ad ) );
  216. }
  217. // done
  218. return( true );
  219. }
  220. bool RemoteCollectionQuery::
  221. Current( string &key, ClassAd *& ad )
  222. {
  223. if( !accumulate ) return( false );
  224. if( itr != results.end( ) ) {
  225. key = itr->first;
  226. ad = itr->second;
  227. return( true );;
  228. }
  229. return( false );
  230. }
  231. bool RemoteCollectionQuery::
  232. Prev( string &key, ClassAd *& ad )
  233. {
  234. if( !accumulate ) return( false );
  235. // already at beginning
  236. if( itr == results.begin( ) ) {
  237. return( false );
  238. }
  239. itr--;
  240. key = itr->first;
  241. ad = itr->second;
  242. return( true );
  243. }
  244. bool RemoteCollectionQuery::
  245. ToAfterLast( )
  246. {
  247. if( !accumulate ) return( false );
  248. itr = results.end( );
  249. return( true );
  250. }
  251. bool RemoteCollectionQuery::
  252. IsAfterLast( ) const
  253. {
  254. if( !accumulate ) return( false );
  255. return( results.end( ) == itr );
  256. }
  257. } // namespace classad