Collection syntax change because of Sonar
[aaf/authz.git] / auth / auth-certman / src / main / java / org / onap / aaf / auth / cm / facade / FacadeImpl.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */
21
22 package org.onap.aaf.auth.cm.facade;
23
24 import static org.onap.aaf.auth.layer.Result.ERR_ActionNotCompleted;
25 import static org.onap.aaf.auth.layer.Result.ERR_BadData;
26 import static org.onap.aaf.auth.layer.Result.ERR_ConflictAlreadyExists;
27 import static org.onap.aaf.auth.layer.Result.ERR_Denied;
28 import static org.onap.aaf.auth.layer.Result.ERR_NotFound;
29 import static org.onap.aaf.auth.layer.Result.ERR_NotImplemented;
30 import static org.onap.aaf.auth.layer.Result.ERR_Policy;
31 import static org.onap.aaf.auth.layer.Result.ERR_Security;
32 import static org.onap.aaf.auth.layer.Result.OK;
33
34 import java.io.IOException;
35 import java.security.KeyStore;
36 import java.security.KeyStoreException;
37 import java.security.NoSuchAlgorithmException;
38 import java.security.PrivateKey;
39 import java.security.cert.Certificate;
40 import java.security.cert.CertificateException;
41 import java.security.cert.X509Certificate;
42 import java.util.ArrayList;
43 import java.util.Collection;
44 import java.util.List;
45
46 import javax.servlet.http.HttpServletRequest;
47 import javax.servlet.http.HttpServletResponse;
48
49 import org.onap.aaf.auth.cm.AAF_CM;
50 import org.onap.aaf.auth.cm.ca.CA;
51 import org.onap.aaf.auth.cm.data.CertResp;
52 import org.onap.aaf.auth.cm.mapper.Mapper;
53 import org.onap.aaf.auth.cm.mapper.Mapper.API;
54 import org.onap.aaf.auth.cm.service.CMService;
55 import org.onap.aaf.auth.dao.cass.ArtiDAO;
56 import org.onap.aaf.auth.dao.cass.Status;
57 import org.onap.aaf.auth.env.AuthzEnv;
58 import org.onap.aaf.auth.env.AuthzTrans;
59 import org.onap.aaf.auth.layer.Result;
60 import org.onap.aaf.cadi.aaf.AAFPermission;
61 import org.onap.aaf.cadi.configure.CertException;
62 import org.onap.aaf.cadi.configure.Factory;
63 import org.onap.aaf.misc.env.APIException;
64 import org.onap.aaf.misc.env.Data;
65 import org.onap.aaf.misc.env.Env;
66 import org.onap.aaf.misc.env.TimeTaken;
67 import org.onap.aaf.misc.env.util.Split;
68 import org.onap.aaf.misc.rosetta.env.RosettaDF;
69 import org.onap.aaf.misc.rosetta.env.RosettaData;
70
71 /**
72  * AuthzFacade
73  * 
74  * This Service Facade encapsulates the essence of the API Service can do, and provides
75  * a single created object for elements such as RosettaDF.
76  *
77  * The Responsibilities of this class are to:
78  * 1) Interact with the Service Implementation (which might be supported by various kinds of Backend Storage)
79  * 2) Validate incoming data (if applicable)
80  * 3) Convert the Service response into the right Format, and mark the Content Type
81  *              a) In the future, we may support multiple Response Formats, aka JSON or XML, based on User Request.
82  * 4) Log Service info, warnings and exceptions as necessary
83  * 5) When asked by the API layer, this will create and write Error content to the OutputStream
84  * 
85  * Note: This Class does NOT set the HTTP Status Code.  That is up to the API layer, so that it can be 
86  * clearly coordinated with the API Documentation
87  * 
88  * @author Jonathan
89  *
90  */
91 public abstract class FacadeImpl<REQ,CERT,ARTIFACTS,ERROR> extends org.onap.aaf.auth.layer.FacadeImpl implements Facade<REQ,CERT,ARTIFACTS,ERROR> 
92         {
93         private static final String TRUE = "TRUE";
94         private static final String REQUEST_CERT = "Request New Certificate";
95         private static final String RENEW_CERT = "Renew Certificate";
96         private static final String DROP_CERT = "Drop Certificate";
97         private static final String READ_CERTS_MECHID = "Read Certificates by MechID";
98         private static final String CREATE_ARTIFACTS = "Create Deployment Artifact";
99         private static final String READ_ARTIFACTS = "Read Deployment Artifact";
100         private static final String UPDATE_ARTIFACTS = "Update Deployment Artifact";
101         private static final String DELETE_ARTIFACTS = "Delete Deployment Artifact";
102
103         private CMService service;
104
105         private final RosettaDF<ERROR>          errDF;
106         private final RosettaDF<REQ>            certRequestDF, certRenewDF, certDropDF;
107         private final RosettaDF<CERT>           certDF;
108         private final RosettaDF<ARTIFACTS>      artiDF;
109         private Mapper<REQ, CERT, ARTIFACTS, ERROR>     mapper;
110 //      private Slot sCertAuth;
111         private AAF_CM certman;
112         private final String voidResp;
113
114         public FacadeImpl(AAF_CM certman,
115                                           CMService service, 
116                                           Mapper<REQ,CERT,ARTIFACTS,ERROR> mapper, 
117                                           Data.TYPE dataType) throws APIException {
118                 this.service = service;
119                 this.mapper = mapper;
120                 this.certman = certman;
121                 AuthzEnv env = certman.env;
122                 //TODO: Gabe [JUnit] Static issue, talk to Jonathan
123                 (errDF                          = env.newDataFactory(mapper.getClass(API.ERROR))).in(dataType).out(dataType);
124                 (certRequestDF          = env.newDataFactory(mapper.getClass(API.CERT_REQ))).in(dataType).out(dataType);
125                 (certRenewDF            = env.newDataFactory(mapper.getClass(API.CERT_RENEW))).in(dataType).out(dataType);
126                 (certDropDF             = env.newDataFactory(mapper.getClass(API.CERT_DROP))).in(dataType).out(dataType);
127                 (certDF                         = env.newDataFactory(mapper.getClass(API.CERT))).in(dataType).out(dataType);
128                 (artiDF                         = env.newDataFactory(mapper.getClass(API.ARTIFACTS))).in(dataType).out(dataType);
129 //              sCertAuth = env.slot(API_Cert.CERT_AUTH);
130                 if(artiDF.getOutType().name().contains("xml")) {
131                         voidResp = "application/Void+xml;charset=utf-8;version=1.0,application/xml;version=1.0,*/*";
132                 } else {
133                         voidResp = "application/Void+json;charset=utf-8;version=1.0,application/json;version=1.0,*/*";
134                 }
135         }
136         
137         public Mapper<REQ,CERT,ARTIFACTS,ERROR> mapper() {
138                 return mapper;
139         }
140         
141         /* (non-Javadoc)
142          * @see com.att.authz.facade.AuthzFacade#error(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletResponse, int)
143          * 
144          * Note: Conforms to AT&T TSS RESTful Error Structure
145          */
146         @Override
147         public void error(AuthzTrans trans, HttpServletResponse response, Result<?> result) {
148                 error(trans, response, result.status,
149                                 result.details==null?"":result.details.trim(),
150                                 result.variables==null?new String[0]:result.variables);
151         }
152                 
153         @Override
154         public void error(AuthzTrans trans, HttpServletResponse response, int status, final String _msg, final String ... _detail) {
155                 String msgId;
156                 String prefix;
157                 boolean hidemsg=false;
158                 switch(status) {
159                         case 202:
160                         case ERR_ActionNotCompleted:
161                                 msgId = "SVC1202";
162                                 prefix = "Accepted, Action not complete";
163                                 response.setStatus(/*httpstatus=*/202);
164                                 break;
165
166                         case 403:
167                         case ERR_Policy:
168                         case ERR_Security:
169                         case ERR_Denied:
170                                 msgId = "SVC1403";
171                                 prefix = "Forbidden";
172                                 response.setStatus(/*httpstatus=*/403);
173                                 break;
174                                 
175                         case 404:
176                         case ERR_NotFound:
177                                 msgId = "SVC1404";
178                                 prefix = "Not Found";
179                                 response.setStatus(/*httpstatus=*/404);
180                                 break;
181
182                         case 406:
183                         case ERR_BadData:
184                                 msgId="SVC1406";
185                                 prefix = "Not Acceptable";
186                                 response.setStatus(/*httpstatus=*/406);
187                                 break;
188                                 
189                         case 409:
190                         case ERR_ConflictAlreadyExists:
191                                 msgId = "SVC1409";
192                                 prefix = "Conflict Already Exists";
193                                 response.setStatus(/*httpstatus=*/409);
194                                 break;
195                         
196                         case 501:
197                         case ERR_NotImplemented:
198                                 msgId = "SVC1501";
199                                 prefix = "Not Implemented"; 
200                                 response.setStatus(/*httpstatus=*/501);
201                                 break;
202                                 
203
204                         default:
205                                 msgId = "SVC1500";
206                                 prefix = "General Service Error";
207                                 response.setStatus(/*httpstatus=*/500);
208                                 hidemsg=true;
209                                 break;
210                 }
211
212                 try {
213                         StringBuilder holder = new StringBuilder();
214                         ERROR em = mapper().errorFromMessage(holder, msgId,prefix + ": " + _msg,_detail);
215                         trans.checkpoint(
216                                         "ErrResp [" + 
217                                         msgId +
218                                         "] " +
219                                         holder.toString(),
220                                         Env.ALWAYS);
221                         if(hidemsg) {
222                                 holder.setLength(0);
223                                 em = mapper().errorFromMessage(holder, msgId, "Server had an issue processing this request");
224                         }
225                         errDF.newData(trans).load(em).to(response.getOutputStream());
226                         
227                 } catch (Exception e) {
228                         trans.error().log(e,"unable to send response for",_msg);
229                 }
230         }
231
232         @Override
233         public Result<Void> check(AuthzTrans trans, HttpServletResponse resp, String perm) throws IOException {
234                 String[] p = Split.split('|',perm);
235                 if(p.length!=3) {
236                         return Result.err(Result.ERR_BadData,"Invalid Perm String");
237                 }
238                 AAFPermission ap = new AAFPermission(p[0],p[1],p[2]);
239                 if(certman.aafLurPerm.fish(trans.getUserPrincipal(), ap)) {
240                         resp.setContentType(voidResp);
241                         resp.getOutputStream().write(0);
242                         return Result.ok();
243                 } else {
244                         return Result.err(Result.ERR_Denied,"%s does not have %s",trans.user(),ap.getKey());
245                 }
246         }
247
248         /* (non-Javadoc)
249          * @see com.att.auth.certman.facade.Facade#requestCert(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
250          */
251         @Override
252         public Result<Void> requestCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, CA ca) {
253                 TimeTaken tt = trans.start(REQUEST_CERT, Env.SUB|Env.ALWAYS);
254                 String wt;
255                 boolean withTrust=(wt=req.getParameter("withTrust"))!=null || TRUE.equalsIgnoreCase(wt);
256                 try {
257                         REQ request;
258                         try {
259                                 Data<REQ> rd = certRequestDF.newData().load(req.getInputStream());
260                                 request = rd.asObject();
261                         } catch(APIException e) {
262                                 trans.error().log("Invalid Input",IN,REQUEST_CERT);
263                                 return Result.err(Result.ERR_BadData,"Invalid Input");
264                         }
265                         
266                         Result<CertResp> rcr = service.requestCert(trans,mapper.toReq(trans,request), ca);
267                         if(rcr.notOK()) {
268                                 return Result.err(rcr);
269                         }
270                         
271 //                      CA certAuth = trans.get(sCertAuth,null);
272                         Result<CERT> rc = mapper.toCert(trans, rcr, withTrust);
273                         switch(rc.status) {
274                                 case OK: 
275                                         RosettaData<CERT> data = certDF.newData(trans).load(rc.value);
276                                         data.to(resp.getOutputStream());
277         
278                                         setContentType(resp,certDF.getOutType());
279                                         return Result.ok();
280                                 default:
281                                         return Result.err(rc);
282                         }
283
284                 } catch (Exception e) {
285                         trans.error().log(e,IN,REQUEST_CERT);
286                         return Result.err(e);
287                 } finally {
288                         tt.done();
289                 }
290         }
291         
292         /* (non-Javadoc)
293          * @see org.onap.aaf.auth.cm.facade.Facade#requestPersonalCert(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, boolean)
294          */
295         @Override
296         public Result<Void> requestPersonalCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, CA ca) {
297                 return Result.err(Result.ERR_NotImplemented,"not implemented yet");
298 //              Result<CertResp> rcr = service.requestPersonalCert(trans,ca);
299 //              if(rcr.notOK()) {
300 //                      return Result.err(rcr);
301 //              } else {
302 //                      try {
303 //                              resp.setContentType("application/zip, application/octet-stream");
304 //                              ZipOutputStream zos = new ZipOutputStream(resp.getOutputStream());
305 //                              PrintStream ps = new PrintStream(zos);
306 //                              ZipEntry ze = new ZipEntry(trans.user()+".key");
307 //                              zos.putNextEntry(ze);
308 //                              ps.print(rcr.value.privateString());
309 //                              zos.closeEntry();
310 //
311 //                              zos.putNextEntry(new ZipEntry(trans.user()+".crt"));
312 //                              ps.print(rcr.value.asCertString());
313 //                              zos.closeEntry();
314 //                              
315 //                              String wt;
316 //                              if((wt=req.getParameter("withTrust"))!=null || TRUE.equalsIgnoreCase(wt)) {
317 //                                      zos.putNextEntry(new ZipEntry(trans.user()+".trustCrts"));
318 //                                      for(String s : ca.getTrustChain()) {
319 //                                              ps.println(s);
320 //                                      }
321 //                                      zos.closeEntry();
322 //                              }
323 //                              
324 //                              boolean withJKS = (wt=req.getParameter("withJKS"))!=null || TRUE.equalsIgnoreCase(wt);
325 //                              if(withJKS) {
326 //                                      if(trans.getUserPrincipal() instanceof BasicPrincipal) {
327 //                                              char[] cap = new String(((BasicPrincipal)trans.getUserPrincipal()).getCred()).toCharArray();
328 //                                              KeyStore ks = keystore(trans, rcr.value, ca.getTrustChain(), trans.user(), cap);
329 //                                              zos.putNextEntry(new ZipEntry(trans.user()+".jks"));
330 //                                              ks.store(zos, cap);
331 //                                              zos.closeEntry();
332 //                                      }
333 //                              }
334 //                              
335 //                              zos.putNextEntry(new ZipEntry("cert_deploy.sh"));
336 //                              ps.println("# Deploy Certificate to ~/.aaf");
337 //                              ps.println("if [ \"$1\" = \"\" ]; then echo \"sh deploy.sh <zipfile>\";exit; else chmod 700 $HOME/.aaf; fi");
338 //                              ps.println("chmod 600 $1");
339 //                              ps.println("if [ ! -e $HOME/.aaf ]; then mkdir -m 700 $HOME/.aaf; fi");
340 //                              ps.println("THE_PWD=`pwd`");
341 //                              ps.println("cd $HOME/.aaf");
342 //                              ps.println("echo \"Deploying to `pwd`\"");
343 //                              ps.println("jar -xvf $THE_PWD/$1 " + trans.user());
344 //                              ps.println("chmod 600 " + trans.user() + ".key");
345 //                              if(withJKS) {
346 //                                      ps.println("chmod 600 " + trans.user() + ".jks");
347 //                              }
348 //                              ps.println("cd $THE_PWD");
349 //                              ps.println("rm cert_deploy.sh");
350 //                              zos.closeEntry();
351 //                              
352 //
353 //                              zos.close();
354 //                              
355 //                      } catch (IOException | KeyStoreException | CertificateException | APIException | CertException | NoSuchAlgorithmException e) {
356 //                              return Result.err(e);
357 //                      }
358 //              }
359 //
360 //              return Result.ok();
361         }
362
363         private KeyStore keystore(AuthzTrans trans, CertResp cr, String[] trustChain, String name, char[] cap) throws KeyStoreException, CertificateException, APIException, IOException, CertException, NoSuchAlgorithmException {
364                 KeyStore jks = KeyStore.getInstance("jks");
365                 jks.load(null, cap);
366                 
367                 // Get the Cert(s)... Might include Trust store
368                 List<String> lcerts = new ArrayList<>();
369                 lcerts.add(cr.asCertString());
370                 for(String s : trustChain) {
371                         lcerts.add(s);
372                 }
373                 
374                 Collection<? extends Certificate> certColl = Factory.toX509Certificate(lcerts);
375                 X509Certificate[] certs = new X509Certificate[certColl.size()];
376                 certColl.toArray(certs);
377                 KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(cap);
378                 
379                 PrivateKey pk = Factory.toPrivateKey(trans, cr.privateString());
380                 KeyStore.PrivateKeyEntry pkEntry = 
381                                 new KeyStore.PrivateKeyEntry(pk, new Certificate[] {certs[0]});
382                 jks.setEntry(name, pkEntry, protParam);
383                 
384                 int i=0;
385                 for(X509Certificate x509 : certs) {
386                         jks.setCertificateEntry("cert_"+ ++i, x509);
387                 }
388                 return jks;
389         }
390
391         @Override
392         public Result<Void> renewCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, boolean withTrust) {
393                 TimeTaken tt = trans.start(RENEW_CERT, Env.SUB|Env.ALWAYS);
394                 try {
395                         REQ request;
396                         try {
397                                 Data<REQ> rd = certRenewDF.newData().load(req.getInputStream());
398                                 request = rd.asObject();
399                         } catch(APIException e) {
400                                 trans.error().log("Invalid Input",IN,RENEW_CERT);
401                                 return Result.err(Result.ERR_BadData,"Invalid Input");
402                         }
403                         
404 //                      String certAuth = trans.get(sCertAuth,null);
405                         Result<CertResp> rcr = service.renewCert(trans,mapper.toRenew(trans,request));
406                         Result<CERT> rc = mapper.toCert(trans, rcr, withTrust);
407
408                         switch(rc.status) {
409                                 case OK: 
410                                         RosettaData<CERT> data = certDF.newData(trans).load(rc.value);
411                                         data.to(resp.getOutputStream());
412
413                                         setContentType(resp,certDF.getOutType());
414                                         return Result.ok();
415                                 default:
416                                         return Result.err(rc);
417                         }
418                 } catch (Exception e) {
419                         trans.error().log(e,IN,RENEW_CERT);
420                         return Result.err(e);
421                 } finally {
422                         tt.done();
423                 }
424
425         }
426
427         @Override
428         public Result<Void> dropCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {
429                 TimeTaken tt = trans.start(DROP_CERT, Env.SUB|Env.ALWAYS);
430                 try {
431                         REQ request;
432                         try {
433                                 Data<REQ> rd = certDropDF.newData().load(req.getInputStream());
434                                 request = rd.asObject();
435                         } catch(APIException e) {
436                                 trans.error().log("Invalid Input",IN,DROP_CERT);
437                                 return Result.err(Result.ERR_BadData,"Invalid Input");
438                         }
439                         
440                         Result<Void> rv = service.dropCert(trans,mapper.toDrop(trans, request));
441                         switch(rv.status) {
442                                 case OK: 
443                                         setContentType(resp,certRequestDF.getOutType());
444                                         return Result.ok();
445                                 default:
446                                         return Result.err(rv);
447                         }
448                 } catch (Exception e) {
449                         trans.error().log(e,IN,DROP_CERT);
450                         return Result.err(e);
451                 } finally {
452                         tt.done();
453                 }
454         }
455
456         /* (non-Javadoc)
457          * @see org.onap.aaf.auth.cm.facade.Facade#readCertsByMechID(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)
458          */
459         @Override
460         public Result<Void> readCertsByMechID(AuthzTrans trans, HttpServletResponse resp, String mechID) {
461                 TimeTaken tt = trans.start(READ_CERTS_MECHID, Env.SUB|Env.ALWAYS);
462                 try {
463                         Result<CERT> rc = mapper.toCert(trans, service.readCertsByMechID(trans,mechID));
464                         switch(rc.status) {
465                                 case OK: 
466                                         RosettaData<CERT> data = certDF.newData(trans).load(rc.value);
467                                         data.to(resp.getOutputStream());
468         
469                                         setContentType(resp,certDF.getOutType());
470                                         return Result.ok();
471                                 default:
472                                         return Result.err(rc);
473                         }
474                 } catch (Exception e) {
475                         trans.error().log(e,IN,READ_CERTS_MECHID);
476                         return Result.err(e);
477                 } finally {
478                         tt.done();
479                 }
480         }
481
482         ////////////////////////////
483         // Artifacts
484         ////////////////////////////
485         @Override
486         public Result<Void> createArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {
487                 TimeTaken tt = trans.start(CREATE_ARTIFACTS, Env.SUB);
488                 try {
489                         ARTIFACTS arti;
490                         try {
491                                 Data<ARTIFACTS> rd = artiDF.newData().load(req.getInputStream());
492                                 arti = rd.asObject();
493                         } catch(APIException e) {
494                                 trans.error().log("Invalid Input",IN,CREATE_ARTIFACTS);
495                                 return Result.err(Result.ERR_BadData,"Invalid Input");
496                         }
497                         
498                         return service.createArtifact(trans,mapper.toArtifact(trans,arti));
499                 } catch (Exception e) {
500
501                         trans.error().log(e,IN,CREATE_ARTIFACTS);
502                         return Result.err(e);
503                 } finally {
504                         tt.done();
505                 }
506         }
507
508         @Override
509         public Result<Void> readArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {
510                 TimeTaken tt = trans.start(READ_ARTIFACTS, Env.SUB);
511                 try {
512                         String mechid = req.getParameter("mechid");
513                         String machine = req.getParameter("machine");
514                         String ns = req.getParameter("ns");
515                         
516                         Result<ARTIFACTS> ra;
517                         if( machine !=null && mechid == null) {
518                                 ra = mapper.fromArtifacts(service.readArtifactsByMachine(trans, machine));
519                         } else if(mechid!=null && machine==null) {
520                                 ra = mapper.fromArtifacts(service.readArtifactsByMechID(trans, mechid));
521                         } else if(mechid!=null && machine!=null) {
522                                 ArtiDAO.Data add = new ArtiDAO.Data();
523                                 add.mechid = mechid;
524                                 add.machine = machine;
525                                 add.ns = ns;
526                                 ra = mapper.fromArtifacts(service.readArtifacts(trans,add));
527                         } else if(ns!=null) {
528                                 ra = mapper.fromArtifacts(service.readArtifactsByNs(trans, ns));
529                         } else {
530                                 ra = Result.err(Status.ERR_BadData,"Invalid request inputs");
531                         }
532                         
533                         if(ra.isOK()) {
534                                 RosettaData<ARTIFACTS> data = artiDF.newData(trans).load(ra.value);
535                                 data.to(resp.getOutputStream());
536                                 setContentType(resp,artiDF.getOutType());
537                                 return Result.ok();
538                         } else {
539                                 return Result.err(ra);
540                         }
541
542                 } catch (Exception e) {
543                         trans.error().log(e,IN,READ_ARTIFACTS);
544                         return Result.err(e);
545                 } finally {
546                         tt.done();
547                 }
548         }
549
550         @Override
551         public Result<Void> readArtifacts(AuthzTrans trans, HttpServletResponse resp, String mechid, String machine) {
552                 TimeTaken tt = trans.start(READ_ARTIFACTS, Env.SUB);
553                 try {
554                         ArtiDAO.Data add = new ArtiDAO.Data();
555                         add.mechid = mechid;
556                         add.machine = machine;
557                         Result<ARTIFACTS> ra = mapper.fromArtifacts(service.readArtifacts(trans,add));
558                         if(ra.isOK()) {
559                                 RosettaData<ARTIFACTS> data = artiDF.newData(trans).load(ra.value);
560                                 data.to(resp.getOutputStream());
561                                 setContentType(resp,artiDF.getOutType());
562                                 return Result.ok();
563                         } else {
564                                 return Result.err(ra);
565                         }
566                 } catch (Exception e) {
567                         trans.error().log(e,IN,READ_ARTIFACTS);
568                         return Result.err(e);
569                 } finally {
570                         tt.done();
571                 }
572         }
573
574
575         @Override
576         public Result<Void> updateArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {
577                 TimeTaken tt = trans.start(UPDATE_ARTIFACTS, Env.SUB);
578                 try {
579                         ARTIFACTS arti;
580                         try {
581                                 Data<ARTIFACTS> rd = artiDF.newData().load(req.getInputStream());
582                                 arti = rd.asObject();
583                         } catch(APIException e) {
584                                 trans.error().log("Invalid Input",IN,UPDATE_ARTIFACTS);
585                                 return Result.err(Result.ERR_BadData,"Invalid Input");
586                         }
587                         
588                         return service.updateArtifact(trans,mapper.toArtifact(trans,arti));
589                 } catch (Exception e) {
590                         trans.error().log(e,IN,UPDATE_ARTIFACTS);
591                         return Result.err(e);
592                 } finally {
593                         tt.done();
594                 }
595         }
596
597         @Override
598         public Result<Void> deleteArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {
599                 TimeTaken tt = trans.start(DELETE_ARTIFACTS, Env.SUB);
600                 try {
601                         ARTIFACTS arti;
602                         try {
603                                 Data<ARTIFACTS> rd = artiDF.newData().load(req.getInputStream());
604                                 arti = rd.asObject();
605                         } catch(APIException e) {
606                                 trans.error().log("Invalid Input",IN,DELETE_ARTIFACTS);
607                                 return Result.err(Result.ERR_BadData,"Invalid Input");
608                         }
609                         
610                         Result<Void> rv = service.deleteArtifact(trans,mapper.toArtifact(trans,arti));
611                         switch(rv.status) {
612                                 case OK: 
613                                         setContentType(resp,artiDF.getOutType());
614                         } 
615                         return rv;
616                 } catch (Exception e) {
617                         trans.error().log(e,IN,DELETE_ARTIFACTS);
618                         return Result.err(e);
619                 } finally {
620                         tt.done();
621                 }
622         }
623
624         @Override
625         public Result<Void> deleteArtifacts(AuthzTrans trans, HttpServletResponse resp, String mechid, String machine) {
626                 TimeTaken tt = trans.start(DELETE_ARTIFACTS, Env.SUB);
627                 try {
628                         Result<Void> rv = service.deleteArtifact(trans, mechid, machine);
629                         switch(rv.status) {
630                                 case OK: 
631                                         setContentType(resp,artiDF.getOutType());
632                         } 
633                         return rv;
634                 } catch (Exception e) {
635                         trans.error().log(e,IN,DELETE_ARTIFACTS);
636                         return Result.err(e);
637                 } finally {
638                         tt.done();
639                 }
640         }
641
642
643 }