Pagina Principale   Moduli   Lista dei namespaces   Gerarchia delle classi   Lista in ordine alfabetico   Lista dei composti   Lista dei files   Membri dei namespaces   Membri dei composti   Membri dei files   Esempi  

/home/fbassi/devel/projects/reti/Proxy/Proxy_i.cc

Vai alla documentazione di questo file.
00001 /*
00002  *    FBFS Distributed Object Repository
00003  *    Copyright (C) 2001 Francesco V. Bassi
00004  *
00005  *    This program is free software; you can redistribute it and/or modify
00006  *    it under the terms of the GNU General Public License as published by
00007  *    the Free Software Foundation; either version 2 of the License, or
00008  *    (at your option) any later version.
00009  *
00010  *    This program is distributed in the hope that it will be useful,
00011  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *    GNU General Public License for more details.
00014  *
00015  *    You should have received a copy of the GNU General Public License
00016  *    along with this program; if not, write to the Free Software
00017  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00025 #include "Proxy_i.h"
00026 #include "../idl/Storage.hh"
00027 #include "../idl/Object.hh"
00028 #include "../idl/ObjectManager.hh"
00029 #include "../Object/Object.h"
00030 #include "../utils/File.h"
00031 #include "../utils/NameServer.h"
00032 #include "../utils/URI.h"
00033 
00034 using utils::File;
00035 
00036 fbfs::Proxy_i::Proxy_i(utils::Prefs &p, const CORBA::ORB_ptr &o)
00037     : prefs(p), orb(o), dir(p.get("cachedir","data")), nsclient(o, p, "", "") {};
00038 
00039 fbfs::Obj *fbfs::Proxy_i::get(const Security &cert, const Obj_id &id)
00040         throw(NotFound, SecurityException, InternalError) {
00041     fbfs::Storage_var storage;
00042     string storage_name;
00043     Obj_ts rem_ts;
00044     string ident(id.name);
00045 
00046     // Accesso shared, in principio. Se poi non c'č il file e devo
00047     // prelevarlo dal server, allora ottengo un accesso exclusive
00048     lock.lock(ident);
00049     
00050     int level=0;
00051     try {
00052         string strobj = File::read(ident, dir);
00053         level = 1;
00054         
00055         string strobj_ts = File::read(ident+".ts", dir );
00056         Obj_ts loc_ts = Object::string2Obj_ts(strobj_ts);
00057         level = 2;
00058         
00059         storage_name = File::read(ident+".server", dir);
00060         level = 3;
00061         
00062         utils::URI uri(storage_name);
00063         
00064         CORBA::Object_ptr obj = utils::NameServer::get_object(orb, uri);
00065         storage = fbfs::Storage::_narrow(obj);
00066         if(CORBA::is_nil(storage)) {
00067             lock.unlock(ident);
00068             throw InternalError();
00069         }
00070         level = 4;
00071         
00072         rem_ts = storage->get_ts(cert, id);
00073         
00074         if( Object::cmp_ts(loc_ts, rem_ts) ) {
00075             lock.unlock(ident);
00076             return Object::string2Obj(strobj);
00077         }
00078     } catch (...) {};
00079 
00080     // Da qui accesso esclusivo al file
00081     lock.unlock(ident);
00082     lock.lock(ident, true);
00083     
00084     // In ogni altro caso: file non trovato sul server remoto, errore del server
00085     // remoto, differenza di ts, etc, rimuovo l'oggetto dalla cache e tento di
00086     // prelevarlo dal server remoto, aggiornando la cache.
00087     try {
00088         switch(level) {
00089             case 4:
00090             case 3:
00091                 File::remove(ident+".server", dir);
00092             case 2:
00093                 File::remove(ident+".ts", dir);
00094             case 1:
00095                 File::remove(ident, dir);
00096         }
00097     } catch (...) {
00098         lock.unlock(ident);
00099         throw InternalError();
00100     };
00101 
00102     // In caso di mancanza di file, fino ad ora non č ancora stato
00103     // contattato il server remoto. Devo risolvere il nome
00104     // dell'ObjectManager che gestisce l'oggetto e ricercare in esso
00105     // l'indirizzo di uno Storage.
00106                 
00107     try {
00108         if(level==0) {
00109             utils::URI uri(nsclient.lookup(id));
00110             if(!uri.isValid())
00111                 throw NotFound();
00112                     
00113             CORBA::Object_ptr obj = utils::NameServer::get_object(orb, uri);
00114             fbfs::ObjectManager_var om = fbfs::ObjectManager::_narrow(obj);
00115             if(CORBA::is_nil(om))
00116                 throw NotFound();
00117             
00118             // Qui ricerco l'indirizzo del server nell'Object Manager 
00119             try {
00120                 CORBA::String_var s = om->lookup(cert, id);
00121                 storage_name = string(s);
00122             
00123                 CORBA::Object_ptr obj = utils::NameServer::get_object( orb, utils::URI(storage_name) );
00124                 storage = fbfs::Storage::_narrow(obj);
00125                 if(CORBA::is_nil(storage))
00126                     throw InternalError();
00127 
00128                 rem_ts = storage->get_ts(cert, id);
00129             } catch(NotFound) {
00130                 throw NotFound();
00131             } catch (...) {
00132                 throw InternalError();
00133             };
00134         };
00135         // Ora il server č contattato. Qualora non abbia prima ricevuto giā
00136         // rem_ts, lo leggo ora.
00137         if(level!=4)
00138             rem_ts = storage->get_ts(cert, id);
00139 
00140         // Prelevo il file.
00141         Obj *o = storage->get(cert, id);
00142 
00143         // Decido se metterlo in cache
00144 
00145         // Lo metto in cache, se ci riesco, senza sollevare polveroni in caso
00146         // di mancanza di riuscita.
00147         level = 0;
00148         try {
00149             File::write( Object::Obj2string(*o), ident, dir, true);
00150             level = 1;
00151             File::write( Object::Obj_ts2string(rem_ts), ident+".ts", dir, true);
00152             level = 2;
00153             File::write( storage_name, ident+".server", dir, true);
00154             level = 3;
00155         } catch (...) {
00156             // Se ci sono problemi, cerco di rimuovere i file rimasti.
00157             try{
00158                 switch(level) {
00159                     case 3:
00160                         File::remove( ident+".server", dir );
00161                     case 2:
00162                         File::remove( ident+".ts", dir );
00163                     case 1:
00164                         File::remove( ident, dir );
00165                 }
00166             } catch (...) {};
00167         };
00168         
00169         // Restituisco un riferimento all'oggetto.
00170         // Si noti che qualora si decida di introdurre delle eccezioni che possano
00171         // capitare tra il o = storage-get() e qui, bisogna provvedere alla rimozione
00172         // dell'area di memoria associata all'oggetto o.
00173         lock.unlock(ident);
00174         return o;
00175     } catch (NotFound) {
00176         lock.unlock(ident);
00177         throw NotFound();
00178     } catch (SecurityException) {
00179         lock.unlock(ident);
00180         throw SecurityException();
00181     } catch (...) {
00182         lock.unlock(ident);
00183         throw InternalError();
00184     };
00185 };
00186 
00187 void fbfs::Proxy_i::put(const Security &cert, const Obj_id &id, const Obj &obj, const Obj_prop &props)
00188         throw(AlreadyPresent, NotFound, SecurityException, InternalError) {
00189     // - Cerco di mettere l'oggetto nel repository.
00190     // - Se ci riesco aggiorno la cache col nuovo oggetto
00191     //   (eventualmente cancellando l'oggetto precedente),
00192     //   prelevando il suo Obj_ts dall'ObjectManager opportuno.
00193     // - Altrimenti lascio la cache come prima.
00194 
00195     utils::URI uri(nsclient.lookup(id));
00196     if(!uri.isValid())
00197         throw NotFound();
00198 
00199     fbfs::ObjectManager_var om;
00200     try {
00201         CORBA::Object_ptr obj = utils::NameServer::get_object(orb, uri);
00202         om = fbfs::ObjectManager::_narrow(obj);
00203     } catch (...) { throw NotFound(); };
00204     if(CORBA::is_nil(om))
00205         throw NotFound();
00206 
00207     // Qui c'č il riferimento all'ObjectManager.
00208     om->put(cert, id, obj, props);
00209 
00210     // Contattando l'ObjectManager, ottengo l'indirizzo di uno Storage,
00211     // che metto in storage_name. Poi contattando lo Storage recupero
00212     // la struttura Obj_ts.
00213     string ident(id.name);
00214     Obj_ts rem_ts; 
00215 
00216     string storage_name;
00217     try {
00218         CORBA::String_var s = om->lookup(cert, id);
00219         storage_name = string(s);
00220         
00221         CORBA::Object_ptr obj = utils::NameServer::get_object( orb, utils::URI(storage_name) );
00222         fbfs::Storage_var storage = fbfs::Storage::_narrow(obj);
00223         if(CORBA::is_nil(storage))
00224             throw InternalError();
00225 
00226         rem_ts = storage->get_ts(cert, id);
00227     } catch (...) {
00228         // Qui andrebbe _molto_ codice per capire cosa fare in questa eventualitā
00229         // rara. Facciamo finta di niente:
00230         // "Never test for an error condition you don't know how to handle."
00231         return;
00232     };
00233 
00234     // Ottengo un accesso esclusivo all'oggetto.
00235     lock.lock(ident, true);
00236     
00237     // Lo metto in cache, se ci riesco, senza sollevare polveroni in caso
00238     // di mancanza di riuscita.
00239     int level = 0;
00240     try {
00241         File::write( Object::Obj2string(obj), ident, dir, true);
00242         level = 1;
00243         File::write( Object::Obj_ts2string(rem_ts), ident+".ts", dir, true);
00244         level = 2;
00245         File::write( storage_name, ident+".server", dir, true);
00246         level = 3;
00247     } catch (...) {
00248         // Se ci sono problemi, cerco di rimuovere i file rimasti.
00249         try{
00250             switch(level) {
00251                 case 3:
00252                     File::remove( ident+".server", dir );
00253                 case 2:
00254                     File::remove( ident+".ts", dir );
00255                 case 1:
00256                     File::remove( ident, dir );
00257             }
00258         } catch (...) {};
00259     };
00260     lock.unlock(ident);
00261 };
00262 
00263 void fbfs::Proxy_i::remove(const Security &cert, const Obj_id &id)
00264         throw(NotFound, SecurityException, InternalError) {
00265     // - Cerco di rimuovere l'oggetto dal repository.
00266     // - Se ci riesco cancello l'eventuale copia in cache.
00267 
00268     utils::URI uri(nsclient.lookup(id));
00269     if(!uri.isValid())
00270         throw NotFound();
00271 
00272     string ident(id.name);
00273 
00274     CORBA::Object_ptr obj = utils::NameServer::get_object(orb, uri);
00275     fbfs::ObjectManager_var om = fbfs::ObjectManager::_narrow(obj);
00276     if(CORBA::is_nil(om))
00277         throw NotFound();
00278 
00279     lock.lock(ident, true);
00280     try {
00281         om->remove(cert, id);
00282     } catch (...) {
00283         lock.unlock(ident);
00284         throw;
00285     };
00286 
00287     // Se il flusso arriva qui, l'oggetto esisteva nel repository remoto
00288     // ed č stato rimosso con successo.
00289     // Ora lo rimuovo dalla cache, se c'č.
00290     // Approccio ottimista qualora non riesca a rimuoverlo. Anche se rimane,
00291     // infatti non fa danno.
00292     try { File::remove(ident, dir); } catch (...) {};
00293     try { File::remove(ident+".ts", dir); } catch (...) {};
00294     try { File::remove(ident+".server", dir); } catch (...) {};
00295     lock.unlock(ident);
00296 };

Generato il Thu Feb 15 13:24:56 2001 per A Simple Distributed Object Repository with CORBA & C++. da doxygen1.2.3 scritto da Dimitri van Heesch, © 1997-2000