1 package fr.in2p3.jsaga.impl.context;
2
3 import fr.in2p3.jsaga.adaptor.base.defaults.Default;
4 import fr.in2p3.jsaga.adaptor.base.usage.Usage;
5 import fr.in2p3.jsaga.adaptor.security.*;
6 import fr.in2p3.jsaga.engine.factories.SecurityAdaptorFactory;
7 import fr.in2p3.jsaga.engine.session.SessionConfiguration;
8 import fr.in2p3.jsaga.impl.attributes.AbstractAttributesImpl;
9 import fr.in2p3.jsaga.impl.job.service.JobServiceImpl;
10 import org.apache.log4j.Logger;
11 import org.ogf.saga.SagaObject;
12 import org.ogf.saga.context.Context;
13 import org.ogf.saga.error.*;
14
15 import java.io.ByteArrayOutputStream;
16 import java.io.FileNotFoundException;
17 import java.io.PrintStream;
18 import java.util.*;
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public class ContextImpl extends AbstractAttributesImpl implements Context {
33 public static final String URL_PREFIX = "UrlPrefix";
34 public static final String BASE_URL_INCLUDES = "BaseUrlIncludes";
35 public static final String BASE_URL_EXCLUDES = "BaseUrlExcludes";
36 public static final String JOB_SERVICE_ATTRIBUTES = "JobServiceAttributes";
37 public static final String DATA_SERVICE_ATTRIBUTES = "DataServiceAttributes";
38 public static final String RESOURCE_SERVICE_ATTRIBUTES = "ResourceServiceAttributes";
39
40 private static Logger s_logger = Logger.getLogger(ContextImpl.class);
41
42 private ContextAttributes m_attributes;
43 private SecurityAdaptor m_adaptor;
44 private SecurityCredential m_credential;
45 private WeakHashMap<JobServiceImpl,Object> m_jobServices;
46 private SessionConfiguration m_config;
47 private SecurityAdaptorFactory m_adaptorFactory;
48
49
50 public ContextImpl(String type, SessionConfiguration config, SecurityAdaptorFactory adaptorFactory) throws IncorrectStateException, TimeoutException, NoSuccessException {
51 super(null, true);
52 m_attributes = new ContextAttributes(this);
53 m_adaptor = null;
54 m_credential = null;
55 m_jobServices = new WeakHashMap<JobServiceImpl,Object>();
56 m_config = config;
57 m_adaptorFactory = adaptorFactory;
58 if (type!=null && !type.equals("")) {
59 try {
60 this.setAttribute(Context.TYPE, type);
61 }
62 catch (IncorrectStateException e) {throw e;}
63 catch (TimeoutException e) {throw e;}
64 catch (NoSuccessException e) {throw e;}
65 catch (SagaException e) {throw new NoSuccessException(e);}
66 }
67 }
68
69
70 public SagaObject clone() throws CloneNotSupportedException {
71 ContextImpl clone = (ContextImpl) super.clone();
72 clone.m_attributes = m_attributes;
73 clone.m_adaptor = m_adaptor;
74 clone.m_credential = m_credential;
75 clone.m_jobServices = m_jobServices;
76 clone.m_config = m_config;
77 clone.m_adaptorFactory = m_adaptorFactory;
78 return clone;
79 }
80
81
82
83
84 public void setAttribute(String key, String value) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, IncorrectStateException, BadParameterException, DoesNotExistException, TimeoutException, NoSuccessException {
85
86 try {
87 m_attributes.getScalarAttribute(key).setValue(value);
88 } catch (DoesNotExistException e) {
89 super.setAttribute(key, value);
90 }
91
92
93 if (Context.TYPE.equals(key)) {
94
95 m_adaptor = m_adaptorFactory.getSecurityAdaptor(value);
96
97
98 Default[] defaults = m_adaptor.getDefaults(new HashMap());
99 if (defaults != null) {
100 for (int i=0; i<defaults.length; i++) {
101 if (defaults[i].getValue() != null) {
102 super.setAttribute(defaults[i].getName(), defaults[i].getValue());
103 }
104 }
105 }
106
107
108 if (m_config != null) {
109 m_config.setDefaultContext(this);
110 }
111 }
112
113
114 m_credential = null;
115 }
116
117
118 public String getAttribute(String key) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, IncorrectStateException, DoesNotExistException, TimeoutException, NoSuccessException {
119
120 try {
121 return m_attributes.getScalarAttribute(key).getValue();
122 } catch (DoesNotExistException e) {
123
124 SecurityCredential credential = null;
125 try{credential=this.getCredential();} catch(IncorrectStateException e2){
126 if (credential != null) {
127 if (Context.USERID.equals(key)) {
128 try {
129
130 return credential.getUserID();
131 } catch (Exception e2) {
132 throw new NoSuccessException(e2);
133 }
134 } else {
135 try{return credential.getAttribute(key);} catch(NotImplementedException e2){
136 }
137 }
138
139 try {
140 return super.getAttribute(key);
141 } catch (DoesNotExistException dnee) {
142 if (m_adaptor.getUsage().toString().contains(key)) {
143 throw dnee;
144 } else if (Context.USERID.equals(key)) {
145 throw new IncorrectStateException("Attribute not yet initialized. Please first add context to a session.");
146 } else {
147 throw new NoSuccessException("Attribute not supported for this adaptor (or not yet initialized)");
148 }
149 }
150 }
151 }
152
153
154 public void setVectorAttribute(String key, String[] values) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, IncorrectStateException, BadParameterException, DoesNotExistException, TimeoutException, NoSuccessException {
155
156 try {
157 m_attributes.getVectorAttribute(key).setValues(values);
158 } catch (DoesNotExistException e) {
159 super.setVectorAttribute(key, values);
160 }
161
162
163 m_credential = null;
164 }
165
166
167 public String[] getVectorAttribute(String key) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, IncorrectStateException, DoesNotExistException, TimeoutException, NoSuccessException {
168
169 try {
170 return m_attributes.getVectorAttribute(key).getValues();
171 } catch (DoesNotExistException e) {
172 if (Context.USERID.equals(key)) {
173 throw new IncorrectStateException("Operation not allowed on scalar attribute: "+key, this);
174 } else {
175
176 return super.getVectorAttribute(key);
177 }
178 }
179 }
180
181 private String getAttributeFromCredential(String key, SecurityCredential credential) throws NotImplementedException, DoesNotExistException, NoSuccessException {
182 try {
183 return credential.getAttribute(key);
184 } catch (NotImplementedException e) {
185 Usage usage = m_adaptor.getUsage();
186 if (usage!=null && usage.getKeys().contains(key)) {
187 throw new DoesNotExistException("Attribute not set: "+key);
188 } else {
189 throw new NotImplementedException("Attribute not supported: "+key);
190 }
191 }
192 }
193
194
195
196
197
198
199 public void close() {
200 if (m_credential!= null) {
201 try {
202 m_credential.close();
203 } catch (Exception e) {
204 s_logger.warn("Failed to close security adaptor", e);
205 }
206
207 m_credential = null;
208 }
209 }
210
211
212
213
214 public void destroy() throws IncorrectStateException, NoSuccessException {
215 if (m_adaptor== null) {
216 throw new IncorrectStateException("Attribute MUST be set before destroying context: "+Context.TYPE, this);
217 }
218 if (m_adaptor instanceof ExpirableSecurityAdaptor) {
219 try {
220 ((ExpirableSecurityAdaptor) m_adaptor).destroySecurityAdaptor(
221 super._getAttributesMap(), m_attributes.m_type.getValue());
222 } catch (Exception e) {
223 throw new NoSuccessException(e);
224 }
225 }
226
227 m_credential = null;
228 }
229
230
231
232
233 public String toString() {
234 ByteArrayOutputStream stream = new ByteArrayOutputStream();
235 PrintStream out = new PrintStream(stream);
236 if (m_credential!= null) {
237 try {
238 m_credential.dump(out);
239 } catch (Exception e) {
240 e.printStackTrace(out);
241 }
242 } else {
243 out.println("Not yet initialized");
244 }
245 out.close();
246 return stream.toString();
247 }
248
249
250
251
252 public synchronized Class getCredentialClass() throws BadParameterException {
253 if (m_adaptor== null) {
254 throw new BadParameterException("Attribute MUST be set before using context: "+Context.TYPE, this);
255 }
256 return m_adaptor.getSecurityCredentialClass();
257 }
258
259
260
261
262 public synchronized SecurityCredential getCredential() throws NotImplementedException, IncorrectStateException, TimeoutException, NoSuccessException {
263 if (m_adaptor== null) {
264 throw new IncorrectStateException("Attribute MUST be set before using context: "+Context.TYPE, this);
265 }
266
267 return m_credential;
268 }
269
270 public synchronized SecurityCredential createCredential() throws NotImplementedException, IncorrectStateException, TimeoutException, NoSuccessException {
271 Usage usage = m_adaptor.getUsage();
272 Map attributes = super._getAttributesMap();
273
274
275 if (!attributes.isEmpty()) {
276 Set<String> adaptorAttributes;
277 if (usage == null) {
278 adaptorAttributes = new HashSet<String>();
279 } else {
280 adaptorAttributes = usage.getKeys();
281 }
282 adaptorAttributes.addAll(Arrays.asList(Context.TYPE, ContextImpl.URL_PREFIX,
283 ContextImpl.BASE_URL_INCLUDES, ContextImpl.BASE_URL_EXCLUDES,
284 ContextImpl.JOB_SERVICE_ATTRIBUTES, ContextImpl.DATA_SERVICE_ATTRIBUTES,
285 ContextImpl.RESOURCE_SERVICE_ATTRIBUTES));
286 Iterator i = attributes.keySet().iterator();
287 while (i.hasNext()) {
288 Object attr = i.next();
289 if (!adaptorAttributes.contains(attr)) {
290 throw new IncorrectStateException("Invalid attribute: " + attr);
291 }
292 }
293 }
294
295
296 int matching;
297 try {
298 matching = (usage!=null ? usage.getFirstMatchingUsage(attributes) : -1);
299 } catch(DoesNotExistException e) {
300 Usage missing = (usage!=null ? usage.getMissingValues(attributes) : null);
301 if (missing != null) {
302 throw new IncorrectStateException("Missing attribute(s): "+missing.toString(), this);
303 } else {
304 throw new NoSuccessException("[INTERNAL ERROR] Unexpected exception", this);
305 }
306 } catch (BadParameterException e) {
307 throw new IncorrectStateException("Invalid attribute(s): " + e.getMessage(), e);
308 } catch (FileNotFoundException e) {
309
310 throw new IncorrectStateException("Invalid attribute(s): " + e.getMessage(), e);
311 }
312 m_credential = m_adaptor.createSecurityCredential(
313 matching, attributes, m_attributes.m_type.getValue());
314 if (m_credential== null) {
315 throw new NotImplementedException("[INTERNAL ERROR] Method createSecurityCredential should never return 'null'");
316 }
317
318
319 Set<JobServiceImpl> jobServices = new HashSet<JobServiceImpl>();
320 jobServices.addAll(m_jobServices.keySet());
321 new Thread(new JobServiceReset(jobServices, m_credential)).start();
322 return m_credential;
323 }
324
325
326
327
328 public String getSchemeFromAlias(String alias) throws NotImplementedException, NoSuccessException {
329 String urlPrefix;
330 try{urlPrefix=m_attributes.m_urlPrefix.getValue()+"-";} catch(IncorrectStateException e){throw new NoSuccessException(e);}
331 if (alias.startsWith(urlPrefix)) {
332 return alias.substring(urlPrefix.length());
333 } else {
334 String scheme = m_attributes.m_baseUrlIncludes.getSchemeFromAlias(alias);
335 if (scheme != null) {
336 return scheme;
337 } else {
338 return alias;
339 }
340 }
341 }
342
343
344
345
346 public Properties getServiceConfig(String serviceType, String scheme) {
347 if (JOB_SERVICE_ATTRIBUTES.equals(serviceType)) {
348 return m_attributes.m_jobServiceAttributes.getServiceConfig(scheme);
349 } else if (DATA_SERVICE_ATTRIBUTES.equals(serviceType)) {
350 return m_attributes.m_dataServiceAttributes.getServiceConfig(scheme);
351 } else if (RESOURCE_SERVICE_ATTRIBUTES.equals(serviceType)) {
352 return m_attributes.m_resourceServiceAttributes.getServiceConfig(scheme);
353 } else {
354 return null;
355 }
356 }
357
358
359
360
361 public void throwIfConflictsWith(ContextImpl ref) throws NoSuccessException {
362 try {
363 m_attributes.m_baseUrlIncludes.throwIfConflictsWith(
364 m_attributes.m_urlPrefix.getValue(),
365 ref.m_attributes.m_urlPrefix.getValue(),
366 ref.m_attributes.m_baseUrlIncludes,
367 ref.m_attributes.m_baseUrlExcludes,
368 m_attributes.m_baseUrlExcludes);
369 }
370 catch (NoSuccessException e) {throw e;}
371 catch (SagaException e) {throw new NoSuccessException(e);}
372 }
373
374
375
376
377 public boolean matches(String url) {
378
379 if (m_attributes.m_baseUrlExcludes.matches(url)) {
380 return false;
381 }
382
383 return m_attributes.m_baseUrlIncludes.matches(url);
384 }
385
386
387
388
389 public void setUrlPrefix(int position) throws NoSuccessException {
390 try {
391 if (m_attributes.m_urlPrefix.getValue() == null) {
392 m_attributes.m_urlPrefix.setValue(m_attributes.m_type.getValue()+position);
393 }
394 }
395 catch (NoSuccessException e) {throw e;}
396 catch (SagaException e) {throw new NoSuccessException(e);}
397 }
398
399
400
401
402 public synchronized void registerJobService(JobServiceImpl jobService) {
403 m_jobServices.put(jobService, new Object());
404 }
405
406
407 public String getUsage() {
408 Usage usage = m_adaptor.getUsage();
409 if (usage != null) {
410 return usage.toString();
411 }
412 return null;
413 }
414
415 public String getDefault(String key) throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, IncorrectStateException, DoesNotExistException, TimeoutException, NoSuccessException {
416
417 if (super.isVectorAttribute(key)) {
418 return Arrays.toString(super.getVectorAttribute(key));
419 } else {
420 return super.getAttribute(key);
421 }
422 }
423
424 public String getMissings() throws NotImplementedException, AuthenticationFailedException, AuthorizationFailedException, PermissionDeniedException, DoesNotExistException, IncorrectStateException, TimeoutException, NoSuccessException {
425 Map<String,String> defaults = new HashMap<String,String>();
426 for (String key : this.listAttributes()) {
427 defaults.put(key, this.getDefault(key));
428 }
429 Usage usage = m_adaptor.getUsage();
430 if (usage != null) {
431 Usage missing = usage.getMissingValues(defaults);
432 if (missing != null) {
433 return missing.toString();
434 }
435 }
436 return null;
437 }
438 }