Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/mobicents/slee/runtime/SbbEntityFactory.java


1   /*
2    * Created on Feb 3, 2005
3    * 
4    * The Mobicents Open SLEE Project
5    * 
6    * A SLEE for the People
7    * 
8    * The source code contained in this file is in in the public domain.          
9    * It can be used in any project or product without prior permission,         
10   * license or royalty payments. There is no claim of correctness and
11   * NO WARRANTY OF ANY KIND provided with this code.
12   */
13  package org.mobicents.slee.runtime;
14  
15  import java.rmi.dgc.VMID;
16  import java.util.HashMap;
17  
18  import javax.slee.SbbID;
19  import javax.slee.ServiceID;
20  import javax.transaction.SystemException;
21  
22  import org.jboss.logging.Logger;
23  import org.mobicents.slee.container.SleeContainer;
24  import org.mobicents.slee.runtime.SbbEntity.PrepareAction;
25  import org.mobicents.slee.runtime.transaction.TransactionManagerImpl;
26  
27  /**
28   * 
29   * SbbEntityFactory -- implements a map from SBB Entity Id to SBB Entity instances.
30   * This is the sole place where Sbb Entities are created and destroyed.
31   * We keep a map of SBB Entity ID to SBB Entity here and return Sbb Entities that
32   * are stored in this map.
33   * 
34   * @author F.Moggia
35   * @author M. Ranganathan
36   * @author Tim Fox  ( streamlining )
37   */
38  public class SbbEntityFactory {
39    
40    /* NB!! We must not a map to cache sbb entities.
41       * There can be multiple active transactions each of which accesses the same sbb entity
42       * at any one time in the SLEE.
43       * Therefore, by using a map to store the sbb entities one tx can see the transactional
44       * state of the other tx before it has committed.
45       * I.e. we would have no transaction isolation.
46       * Instead, if we want to cache the sbb entity for the lifetime of the tx for
47       * performance reasons, we need to store in a *per transaction* cache
48       */
49    
50      private static String tcache = TransactionManagerImpl.TCACHE;
51      
52      private SleeContainer serviceContainer;
53  
54      //private static int counter;
55      
56      private static Logger log = Logger.getLogger(SbbEntityFactory.class);
57      
58  
59      public SbbEntityFactory(SleeContainer container) {
60          this.serviceContainer = container;
61      }
62  
63      private String genId()
64      {
65        //Use a GUID for the sbb entity id - a counter won't work in a cluster
66        VMID vmid = new VMID();
67        return vmid.toString();
68      }
69      
70      public SbbEntity createSbbEntity(SbbID sbbId, ServiceID svcId,
71              String parentSbbEntityId, String convergenceName) {
72          try {                    
73              String sbbeId = genId();
74              log.debug("createSbbEntity: Creating non-root sbb entity with id:" + sbbeId);
75              
76              SbbEntity sbbe = new SbbEntity(this.serviceContainer, sbbeId,
77                      sbbId, convergenceName, svcId);
78              sbbe.setParentSbbEntity(parentSbbEntityId);
79              sbbe.setRootSbbId(this.serviceContainer.getService(svcId)
80                      .getRootSbbEntityId(convergenceName));
81              
82              // storing in cache is deferred until successful commit.
83              
84              log.debug("Putting it in the map");
85              putInTxCache(sbbeId, sbbe);
86              return sbbe;
87          } catch (Exception ex) {
88              String s = "unexpected error in creating sbbEntity!";
89              log.error(s,ex);
90              throw new RuntimeException(s, ex);
91          }
92      }
93  
94      public SbbEntity createRootSbbEnity(SbbID sbbId, ServiceID svcId,
95              String convergenceName) {
96          try {
97              String sbbeId = genId();
98              
99              log.debug("Creating root sbb entity with id:" + sbbeId);
100             
101             SbbEntity sbbe = new SbbEntity(this.serviceContainer, sbbeId,
102                     sbbId, convergenceName, svcId);
103             sbbe.setParentSbbEntity(sbbeId);
104             sbbe.setRootSbbId(sbbeId);
105            // Defer the store to cache until the enclosing tx commits.
106             log.debug("Putting it in the map");
107             putInTxCache(sbbeId, sbbe);
108             return sbbe;
109         } catch (Exception ex) {
110             String s = "unexpected exception in createSbbEntity";
111             log.error(s,ex);
112             throw new RuntimeException(s, ex); 
113         }
114     }
115 
116     private void putInTxCache(String sbbeID, SbbEntity sbb) {
117       try {
118 
119         SleeContainer.getTransactionManager().putDeferredData("sbb" + sbbeID, sbb);
120         
121       } catch (SystemException e) {
122         String s = "Failed to put sbb in tx cache";
123           log.error(s, e);
124           throw new RuntimeException(s, e);        
125       }
126     }
127    
128     
129     /**
130      * Remove the entity id to entity map. Call this when destroying the
131      * sbb entity -- when we no longer need to hold a reference to it.
132      * 
133      * @param sbbeId
134      */
135     public void removeFromCache(String sbbeId) {        
136       
137       try {
138         SleeContainer.getTransactionManager().removeDeferredData("sbb" + sbbeId);
139       } catch (SystemException e) {
140         String s = "Failed to remove sbb from tx cache";
141           log.error(s, e);
142           throw new RuntimeException(s, e);        
143       }
144       
145       
146     }
147 
148     /**
149      * Call this function when you want to get an instantiated SbbEntity from the
150      * cache.
151      * 
152      * @param sbbeId
153      * @return
154      */
155     public SbbEntity getSbbEntity(String sbbeId) {
156     
157         log.debug("getSbbEntity : " + sbbeId);
158        
159         /* NB!! We must not use a map to cache sbb entities.
160          * There can be multiple active transactions each of which accesses the same sbb entity
161          * at any one time in the SLEE.
162          * Therefore, by using a map to store the sbb entities one tx can see the transactional
163          * state of the other tx before it has committed.
164          * I.e. we would have no transaction isolation.
165          * Instead, if we want to cache the sbb entity for the lifetime of the tx for
166          * performance reasons, we need to store in a *per transaction* cache
167          */
168         
169         try {
170         
171           
172           //Look for it in the per transaction cache
173           SbbEntity sbb = (SbbEntity)SleeContainer.getTransactionManager().getDeferredData("sbb" + sbbeId);
174           
175           if (sbb == null) {
176             //Load it from the treecache         
177             log.debug("Cannot find sbb in per tx cache - loading from treecache");
178             
179             sbb = new SbbEntity(this.serviceContainer, sbbeId);
180             
181             SleeContainer.getTransactionManager().putDeferredData("sbb" + sbbeId, sbb);
182           } else {
183             log.debug("Found sbb in per tx cache");
184 
185           }
186           
187           
188           return sbb;
189           
190         } catch (SystemException e) {
191           String s = "Failed to get sbb from tx cache";
192           log.error(s, e);
193           throw new RuntimeException(s, e);
194         }
195     
196     }
197     
198     public boolean isStale(String sbbeId){
199         try {
200             return  SleeContainer.getTransactionManager().getNode(tcache,"sbbentity" + "/" + sbbeId) == null;
201         } catch (SystemException e) {
202             // TODO Auto-generated catch block
203             String s = "failed to check cache";
204             log.error (s,e);
205             throw new RuntimeException(s,e);
206         }
207     }
208 }