00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #include "ObjectManager_i.h"
00026 #include "../utils/URI.h"
00027 #include "../utils/NameServer.h"
00028 #include "../utils/TimeStamp.h"
00029 #include "../utils/Rand.h"
00030 #include "../idl/Storage.hh"
00031 #include "../Object/Properties.h"
00032
00033 #include <iostream.h>
00034
00035 using namespace fbfs;
00036 using namespace utils;
00037
00038 fbfs::ObjectManager_i::ObjectManager_i(const utils::Prefs &p, const CORBA::ORB_ptr &o)
00039 : prefs(p), orb(o) {
00040
00041
00042 ifstream file;
00043 file.open(prefs.get("hostfile", "objectmanager-server.hosts").c_str());
00044 while(!file.eof()) {
00045 string s;
00046 file >> s;
00047 URI uri(s);
00048 if(uri.isValid())
00049 servers.push_front(s);
00050 };
00051
00052
00053
00054 validate();
00055
00056
00057
00058 };
00059
00060 char *fbfs::ObjectManager_i::lookup(const Security &cert, const Obj_id &id)
00061 throw(NotFound, SecurityException, InternalError) {
00062 string name(id.name);
00063 lock.lock(name);
00064
00065 if( rep.count(name) == 0 ) {
00066 lock.unlock(name);
00067 throw NotFound();
00068 };
00069
00070 Servers &s = rep[name];
00071
00072 if( s.size() < 1 ) {
00073 lock.unlock(name);
00074 throw InternalError();
00075 };
00076
00077
00078
00079
00080
00081 int n = utils::rand(s.size());
00082 Servers::iterator i = s.begin();
00083 while(n-->0)
00084 i++;
00085 lock.unlock(name);
00086 return strdup((*i).c_str());
00087 };
00088
00089 void fbfs::ObjectManager_i::remove(const Security &cert, const Obj_id &id)
00090 throw(PartialExecution, NotFound, SecurityException, InternalError) {
00091 string name(id.name);
00092 lock.lock(name, true);
00093
00094 if( rep.count(name) == 0 ) {
00095 lock.unlock(name);
00096 throw NotFound();
00097 };
00098
00099 Servers &s = rep[name];
00100
00101 if( s.size() < 1) {
00102 lock.unlock(name);
00103 throw InternalError();
00104 };
00105
00106
00107
00108
00109
00110
00111
00112 bool failed = false;
00113
00114 for(Servers::iterator i = s.begin(); i != s.end(); i++) {
00115 URI uri(*i);
00116 try {
00117 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri);
00118 fbfs::Storage_var server = fbfs::Storage::_narrow(obj);
00119 if(CORBA::is_nil(server))
00120 throw InternalError();
00121
00122 server->remove(cert, id);
00123 } catch (...) {
00124
00125
00126 failed = true;
00127 }
00128 }
00129 rep.erase(name);
00130 lock.unlock(name);
00131
00132 if(failed)
00133 throw PartialExecution();
00134 };
00135
00136 void fbfs::ObjectManager_i::put(const Security &cert, const Obj_id &id, const Obj &o, const Obj_prop &p)
00137 throw(PartialExecution, AlreadyPresent, SecurityException, InternalError) {
00138
00139 string name(id.name);
00140 lock.lock(name, true);
00141
00142
00143 if(rep.count(name) != 0) {
00144 lock.unlock(name);
00145 throw AlreadyPresent();
00146 };
00147
00148
00149 Obj_ts ts;
00150 ts.time = utils::TimeStamp::current();
00151
00152
00153 switch(p.type) {
00154 case Properties::DONT_SAVE :
00155 break;
00156 case Properties::REPLICATE_ON_CREAT :
00157 case Properties::REPLICATE_ALWAYS :
00158 case Properties::REPLICATE_MIN_MAX :
00159 {
00160 int ns = servers.size();
00161 int n = p.value_a;
00162 if(n>ns)
00163 n=ns;
00164
00165 Servers itemservers;
00166
00167
00168
00169 Servers::iterator i = servers.begin();
00170 for(int skip = utils::rand(servers.size()); skip-- > 0; i++);
00171 bool failed = false;
00172 while(n--) {
00173 const string &s = (*i);
00174 URI uri(s);
00175
00176
00177
00178 try{
00179 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri);
00180 fbfs::Storage_var server = fbfs::Storage::_narrow(obj);
00181 if(CORBA::is_nil(server))
00182 throw NotFound();
00183 server->put(cert, o, id, p, ts);
00184 itemservers.push_front(s);
00185 } catch (...) {
00186
00187
00188
00189 failed = true;
00190 };
00191
00192 i++;
00193 if(i == servers.end() )
00194 i = servers.begin();
00195 };
00196
00197
00198 if(itemservers.size()==0) {
00199 lock.unlock(name);
00200 throw InternalError();
00201 }
00202
00203
00204
00205 if(p.type == Properties::REPLICATE_MIN_MAX && itemservers.size() < p.value_b) {
00206 Servers::iterator i = itemservers.begin();
00207 while(i != itemservers.end()) {
00208 URI uri(*i);
00209 try {
00210 CORBA::Object_var obj = utils::NameServer::get_object(orb, uri);
00211 fbfs::Storage_var server = fbfs::Storage::_narrow(obj);
00212 if(CORBA::is_nil(server))
00213 throw InternalError();
00214 server->remove(cert, id);
00215 } catch (...) {};
00216 };
00217 lock.unlock(name);
00218 throw InternalError();
00219 };
00220
00221
00222 rep[name] = itemservers;
00223
00224 if(failed) {
00225 lock.unlock(name);
00226 throw PartialExecution();
00227 };
00228 break;
00229 };
00230 default:
00231 lock.unlock(name);
00232 throw InternalError();
00233 };
00234 lock.unlock(name);
00235 };
00236
00237 void fbfs::ObjectManager_i::reparse(const Security &cert) throw(SecurityException) {
00238 };