View Javadoc

1   package fr.in2p3.jsaga.impl.resource.instance;
2   
3   import java.util.Arrays;
4   import java.util.Map.Entry;
5   import java.util.Properties;
6   
7   import fr.in2p3.jsaga.adaptor.resource.ResourceAdaptor;
8   import fr.in2p3.jsaga.adaptor.resource.SecuredResource;
9   import fr.in2p3.jsaga.adaptor.resource.compute.ComputeResourceAdaptor;
10  import fr.in2p3.jsaga.adaptor.resource.compute.SecuredComputeResourceAdaptor;
11  import fr.in2p3.jsaga.adaptor.resource.compute.UnsecuredComputeResourceAdaptor;
12  import fr.in2p3.jsaga.adaptor.resource.network.NetworkResourceAdaptor;
13  import fr.in2p3.jsaga.adaptor.resource.network.SecuredNetworkResourceAdaptor;
14  import fr.in2p3.jsaga.adaptor.resource.network.UnsecuredNetworkResourceAdaptor;
15  import fr.in2p3.jsaga.adaptor.resource.storage.SecuredStorageResourceAdaptor;
16  import fr.in2p3.jsaga.adaptor.resource.storage.StorageResourceAdaptor;
17  import fr.in2p3.jsaga.adaptor.resource.storage.UnsecuredStorageResourceAdaptor;
18  import fr.in2p3.jsaga.helpers.SAGAId;
19  import fr.in2p3.jsaga.impl.context.ContextImpl;
20  import fr.in2p3.jsaga.impl.resource.manager.AbstractSyncResourceManagerImpl;
21  import fr.in2p3.jsaga.impl.resource.manager.ResourceManagerImpl;
22  import fr.in2p3.jsaga.impl.resource.task.AbstractResourceTaskImpl;
23  
24  import org.apache.log4j.Logger;
25  import org.ogf.saga.context.Context;
26  import org.ogf.saga.context.ContextFactory;
27  import org.ogf.saga.error.AuthenticationFailedException;
28  import org.ogf.saga.error.AuthorizationFailedException;
29  import org.ogf.saga.error.BadParameterException;
30  import org.ogf.saga.error.DoesNotExistException;
31  import org.ogf.saga.error.IncorrectStateException;
32  import org.ogf.saga.error.NoSuccessException;
33  import org.ogf.saga.error.NotImplementedException;
34  import org.ogf.saga.error.PermissionDeniedException;
35  import org.ogf.saga.error.TimeoutException;
36  import org.ogf.saga.resource.Type;
37  import org.ogf.saga.resource.description.ComputeDescription;
38  import org.ogf.saga.resource.description.NetworkDescription;
39  import org.ogf.saga.resource.description.ResourceDescription;
40  import org.ogf.saga.resource.description.StorageDescription;
41  import org.ogf.saga.resource.instance.Resource;
42  import org.ogf.saga.resource.manager.ResourceManager;
43  import org.ogf.saga.session.Session;
44  
45  /* ***************************************************
46   * *** Centre de Calcul de l'IN2P3 - Lyon (France) ***
47   * ***             http://cc.in2p3.fr/             ***
48   * ***************************************************/
49  public abstract class AbstractResourceImpl<R extends Resource, RD extends ResourceDescription>
50          extends AbstractResourceTaskImpl<R> implements Resource<R,RD>
51  {
52      protected Logger m_logger = Logger.getLogger(AbstractResourceImpl.class);
53      
54      private RD m_description;
55      private ResourceManager m_manager;
56      private SecuredResource m_securedResourceContext = null;
57      
58      /** constructor for resource acquisition 
59       * @throws DoesNotExistException 
60       * @throws IncorrectStateException 
61       * @throws NoSuccessException 
62       * @throws TimeoutException 
63       * @throws PermissionDeniedException 
64       * @throws AuthorizationFailedException 
65       * @throws AuthenticationFailedException 
66       * @throws NotImplementedException 
67       * @throws BadParameterException */
68      public AbstractResourceImpl(Type type, Session session, ResourceManagerImpl manager, ResourceAdaptor adaptor, RD description) 
69              throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, 
70                      PermissionDeniedException, TimeoutException, NoSuccessException, IncorrectStateException, 
71                      DoesNotExistException, BadParameterException {
72          this(type, session, manager, adaptor);
73          m_attributes.m_Description.setObject(description.toString());
74          // Acquire a new resource and set the ID
75          String resourceId = this.acquireResource(description);
76          m_attributes.m_ResourceID.setObject(SAGAId.idToSagaId(
77                  ((AbstractSyncResourceManagerImpl)m_manager).getURL(), 
78                  resourceId));
79          // reload description
80          this.loadDescription();
81      }
82  
83      /** constructor for reconnecting to resource already acquired 
84       * @throws DoesNotExistException 
85       * @throws NoSuccessException 
86       * @throws TimeoutException 
87       * @throws NotImplementedException 
88       * @throws BadParameterException */
89      public AbstractResourceImpl(Type type, Session session, ResourceManagerImpl manager, ResourceAdaptor adaptor, String id) 
90              throws DoesNotExistException, TimeoutException, NoSuccessException, 
91                      NotImplementedException, BadParameterException {
92          this(type, session, manager, adaptor);
93          // simply set the ID
94          m_attributes.m_ResourceID.setObject(id);
95          // load description of the resource
96          this.loadDescription();
97      }
98  
99      /** common to all constructors 
100      * @throws NotImplementedException */
101     private AbstractResourceImpl(Type type, Session session, ResourceManagerImpl manager, ResourceAdaptor adaptor) throws BadParameterException {
102         super(session, manager, adaptor);
103         m_manager = manager;
104         m_attributes = new ResourceAttributes(this);
105         m_attributes.m_Type.setObject(type);
106         m_attributes.m_ManagerID.setObject(manager.getId());
107         // check that adaptor supports type
108         this.checkDescription();
109     }
110 
111     // getters
112     @Override
113     public Type getType() {
114         return m_attributes.m_Type.getObject();
115     }
116     @Override
117     public ResourceManager getManager() {
118         return m_manager;
119     }
120     
121     /**
122      * Get accesses. Accesses are not required when resource is built because they might be
123      * unavailable before resource is fully ACTIVE.
124      */
125     @Override
126     public String[] getAccess() throws NotImplementedException, AuthenticationFailedException, 
127                     AuthorizationFailedException, TimeoutException, NoSuccessException {
128         try {
129             if (m_attributes.m_Access.getValues().length == 0) {
130                 String[] accesses = m_adaptor.getAccess(SAGAId.idFromSagaId(getId()));
131                 // set access
132                 m_attributes.m_Access.setObjects(accesses);
133                 // now that we have access we can build the context and add it if not already added
134                 if (m_securedResourceContext != null && m_securedResourceContext.getId() != null &&
135                         m_securedResourceContext.getContextType() != null) {
136                     try {
137                         // Add the access to BaseUrlIncludes: this make the context unique
138                         m_securedResourceContext.put(ContextImpl.BASE_URL_INCLUDES, m_attributes.m_Access.getObjects());
139                         // Build the new context
140                         Context context = ContextFactory.createContext(JSAGA_FACTORY, 
141                                 m_securedResourceContext.getContextType());
142                         for (Entry<Object, Object> entry: m_securedResourceContext.entrySet()) {
143                             if (entry.getValue() instanceof String) {
144                                 context.setAttribute((String)entry.getKey(), (String)entry.getValue());
145                             } else if (entry.getValue() instanceof String[]) {
146                                 context.setVectorAttribute((String)entry.getKey(), (String[])entry.getValue());
147                             }
148                         }
149                         // add it to the session
150                         m_session.addContext(context);
151                     } catch (BadParameterException bpe) {
152                         throw new NoSuccessException(bpe);
153                     } catch (PermissionDeniedException e) {
154                         throw new AuthorizationFailedException(e);
155                     }
156                 }
157             }
158         } catch (IncorrectStateException e) {
159             throw new NoSuccessException(e);
160         } catch (DoesNotExistException e) {
161             throw new NoSuccessException(e);
162         } catch (BadParameterException e) {
163             throw new NoSuccessException(e);
164         }
165         return m_attributes.m_Access.getObjects();
166     }
167     
168     @Override
169     public RD getDescription() {
170         return m_description;
171     }
172 
173     protected abstract RD createDescription(Properties description);
174     
175     /** reconfigure 
176      * @throws BadParameterException 
177      * @throws NoSuccessException */
178     public void reconfigure(RD description) throws BadParameterException, NoSuccessException {
179         m_description = description;
180         if (description != null) {
181             m_attributes.m_Description.setObject(description.toString());
182             try {
183                 this.release();
184                 // check that adaptor supports type
185                 String resourceId = this.acquireResource(description);
186                 m_attributes.m_ResourceID.setObject(SAGAId.idToSagaId(
187                         ((AbstractSyncResourceManagerImpl)m_manager).getURL(), 
188                         resourceId));
189                 m_attributes.m_Access.setObjects(m_adaptor.getAccess(SAGAId.idFromSagaId(getId())));
190                 // reload description
191                 this.loadDescription();
192             } catch (Exception e) {
193                 throw new NoSuccessException(e);
194             }
195         }
196     }
197 
198     /** release 
199      * @throws NoSuccessException 
200      * @throws IncorrectStateException */
201     public void release() throws NoSuccessException, IncorrectStateException {
202         try {
203             m_adaptor.release(SAGAId.idFromSagaId(getId()));
204         } catch (DoesNotExistException e) {
205             throw new NoSuccessException(e);
206         } catch (NotImplementedException e) {
207             throw new NoSuccessException(e);
208         } catch (BadParameterException e) {
209             throw new NoSuccessException(e);
210         }
211         // Try to remove security context from session
212         for (Context c: m_session.listContexts()) {
213             try {
214                 if (c.existsAttribute(ContextImpl.BASE_URL_INCLUDES)) {
215                     String[] urls = c.getVectorAttribute(ContextImpl.BASE_URL_INCLUDES);
216                     if (Arrays.equals(urls, m_attributes.m_Access.getObjects())) {
217                         m_logger.debug("Removing context: " + c.getId());
218                         m_session.removeContext(c);
219                         return;
220                     }
221                 }
222             } catch (Exception e) {
223                 m_logger.warn("could not remove context", e);
224             }
225         }
226     }
227 
228 
229     //////////////////
230     // Private methods
231     //////////////////
232     /*
233      * Acquire a resource from a description.
234      * Returns the ID of the acquired resource.
235      */
236     private String acquireResource(RD description) 
237             throws NotImplementedException, NoSuccessException, AuthenticationFailedException, 
238             AuthorizationFailedException, PermissionDeniedException, TimeoutException, 
239             DoesNotExistException, IncorrectStateException {
240         // translate the description into a Properties for the adaptor
241         Properties properties = new Properties();
242         for (String attr: description.listAttributes()) {
243             try { // scalar attribute
244                 properties.setProperty(attr, description.getAttribute(attr));
245             } catch (IncorrectStateException ise) {
246                 properties.put(attr, description.getVectorAttribute(attr));
247             }
248         }
249         if (description instanceof ComputeDescription) {
250             if (m_adaptor instanceof SecuredComputeResourceAdaptor) {
251                 // this adaptor sends back a resourceID along with properties necessary to build a security context
252                 // the security context will be build at getAccess stage as the IP address of the resource may not
253                 // be available yet
254                 m_securedResourceContext = ((SecuredComputeResourceAdaptor)m_adaptor).acquireComputeResource(properties);
255                 // returns the ID only
256                 return m_securedResourceContext.getId();
257             } else if (m_adaptor instanceof UnsecuredComputeResourceAdaptor) {
258                 return ((UnsecuredComputeResourceAdaptor)m_adaptor).acquireComputeResource(properties);
259             }
260         } else if (description instanceof StorageDescription) {
261             if (m_adaptor instanceof SecuredStorageResourceAdaptor) {
262                 m_securedResourceContext = ((SecuredStorageResourceAdaptor)m_adaptor).acquireStorageResource(properties);
263                 return m_securedResourceContext.getId();
264             } else if (m_adaptor instanceof UnsecuredStorageResourceAdaptor) {
265                 return ((UnsecuredStorageResourceAdaptor)m_adaptor).acquireStorageResource(properties);
266             }
267         } else if (description instanceof NetworkDescription) {
268             if (m_adaptor instanceof SecuredNetworkResourceAdaptor) {
269                 m_securedResourceContext = ((SecuredNetworkResourceAdaptor)m_adaptor).acquireNetworkResource(properties);
270                 return m_securedResourceContext.getId();
271             } else if (m_adaptor instanceof UnsecuredNetworkResourceAdaptor) {
272                 return ((UnsecuredNetworkResourceAdaptor)m_adaptor).acquireNetworkResource(properties);
273             }
274         }
275         throw new NotImplementedException("Unkown type of resource adaptor");
276     }
277 
278     /*
279      * Asks the adaptor to send back the resource identified by ID.
280      */
281     private void loadDescription() throws TimeoutException, NoSuccessException, 
282                 DoesNotExistException, NotImplementedException, BadParameterException {
283         // adaptor sends back a properties with resource description
284         Properties description = m_adaptor.getDescription(SAGAId.idFromSagaId(getId()));
285         if (!getType().name().equals(description.getProperty(Resource.RESOURCE_TYPE))) {
286             throw new NotImplementedException(getType().name() + " <> " + description.getProperty(Resource.RESOURCE_TYPE));
287         }
288         // the subclass instantiates the appropriate Resource object
289         m_description = createDescription(description);
290     }
291     
292     /*
293      * checks that the type of resource matches with the adaptor instance
294      */
295     private void checkDescription() throws BadParameterException {
296         this.checkDescription(getType());
297     }
298     
299     /*
300      * checks that the type in parameter matches with the adaptor instance
301      */
302     private void checkDescription(Type type) throws BadParameterException {
303         if (Type.COMPUTE.equals(type) && ! (m_adaptor instanceof ComputeResourceAdaptor)) {
304             throw new BadParameterException("This adaptor does not handle compute resources");
305         }
306         if (Type.STORAGE.equals(type) && ! (m_adaptor instanceof StorageResourceAdaptor)) {
307             throw new BadParameterException("This adaptor does not handle storage resources");
308         }
309         if (Type.NETWORK.equals(type) && ! (m_adaptor instanceof NetworkResourceAdaptor)) {
310             throw new BadParameterException("This adaptor does not handle network resources");
311         }
312         
313     }
314     
315 }