X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=auth%2Fauth-locate%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fauth%2Flocate%2Ffacade%2FLocateFacadeImpl.java;fp=auth%2Fauth-locate%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faaf%2Fauth%2Flocate%2Ffacade%2FLocateFacadeImpl.java;h=1ce9821f7f2133c4669f11b00e4ccf056b2cb022;hb=71037c39a37d3549dcfe31926832a657744fbe05;hp=0000000000000000000000000000000000000000;hpb=a20accc73189d8e5454cd26049c0e6fae75da16f;p=aaf%2Fauthz.git diff --git a/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/facade/LocateFacadeImpl.java b/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/facade/LocateFacadeImpl.java new file mode 100644 index 00000000..1ce9821f --- /dev/null +++ b/auth/auth-locate/src/main/java/org/onap/aaf/auth/locate/facade/LocateFacadeImpl.java @@ -0,0 +1,393 @@ +/** + * ============LICENSE_START==================================================== + * org.onap.aaf + * =========================================================================== + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * =========================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END==================================================== + * + */ + +package org.onap.aaf.auth.locate.facade; + + +import static org.onap.aaf.auth.layer.Result.ERR_ActionNotCompleted; +import static org.onap.aaf.auth.layer.Result.ERR_BadData; +import static org.onap.aaf.auth.layer.Result.ERR_ConflictAlreadyExists; +import static org.onap.aaf.auth.layer.Result.ERR_Denied; +import static org.onap.aaf.auth.layer.Result.ERR_NotFound; +import static org.onap.aaf.auth.layer.Result.ERR_NotImplemented; +import static org.onap.aaf.auth.layer.Result.ERR_Policy; +import static org.onap.aaf.auth.layer.Result.ERR_Security; +import static org.onap.aaf.auth.layer.Result.OK; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.onap.aaf.auth.dao.cass.Status; +import org.onap.aaf.auth.env.AuthzEnv; +import org.onap.aaf.auth.env.AuthzTrans; +import org.onap.aaf.auth.layer.FacadeImpl; +import org.onap.aaf.auth.layer.Result; +import org.onap.aaf.auth.locate.mapper.Mapper; +import org.onap.aaf.auth.locate.mapper.Mapper.API; +import org.onap.aaf.auth.locate.service.LocateService; +import org.onap.aaf.auth.locate.service.LocateServiceImpl; +import org.onap.aaf.auth.rserv.RServlet; +import org.onap.aaf.auth.rserv.RouteReport; +import org.onap.aaf.auth.rserv.doc.ApiDoc; +import org.onap.aaf.cadi.aaf.client.Examples; +import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.env.Data; +import org.onap.aaf.misc.env.Env; +import org.onap.aaf.misc.env.TimeTaken; +import org.onap.aaf.misc.env.Data.TYPE; +import org.onap.aaf.misc.rosetta.env.RosettaDF; +import org.onap.aaf.misc.rosetta.env.RosettaData; + +import locate_local.v1_0.Api; + +/** + * AuthzFacade + * + * This Service Facade encapsulates the essence of the API Service can do, and provides + * a single created object for elements such as RosettaDF. + * + * The Responsibilities of this class are to: + * 1) Interact with the Service Implementation (which might be supported by various kinds of Backend Storage) + * 2) Validate incoming data (if applicable) + * 3) Convert the Service response into the right Format, and mark the Content Type + * a) In the future, we may support multiple Response Formats, aka JSON or XML, based on User Request. + * 4) Log Service info, warnings and exceptions as necessary + * 5) When asked by the API layer, this will create and write Error content to the OutputStream + * + * Note: This Class does NOT set the HTTP Status Code. That is up to the API layer, so that it can be + * clearly coordinated with the API Documentation + * + * @author Jonathan + * + */ +public abstract class LocateFacadeImpl extends FacadeImpl implements LocateFacade + { + private LocateService service; + + private final RosettaDF errDF; + private final RosettaDF apiDF; + private final RosettaDF epDF; + private final RosettaDF mepDF; + + + private static long cacheClear = 0L, emptyCheck=0L; + private final static Map epsCache = new HashMap(); // protected manually, in getEndpoints + + public LocateFacadeImpl(AuthzEnv env, LocateService service, Data.TYPE dataType) throws APIException { + this.service = service; + (errDF = env.newDataFactory(mapper().getClass(API.ERROR))).in(dataType).out(dataType); + (apiDF = env.newDataFactory(Api.class)).in(dataType).out(dataType); + (epDF = env.newDataFactory(mapper().getClass(API.ENDPOINTS))).in(dataType).out(dataType); + (mepDF = env.newDataFactory(mapper().getClass(API.MGMT_ENDPOINTS))).in(dataType).out(dataType); + } + + public Mapper mapper() { + return service.mapper(); + } + + /* (non-Javadoc) + * @see com.att.authz.facade.AuthzFacade#error(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletResponse, int) + * + * Note: Conforms to AT&T TSS RESTful Error Structure + */ + @Override + public void error(AuthzTrans trans, HttpServletResponse response, Result result) { + String msg = result.details==null?"":result.details.trim(); + String[] detail; + if(result.variables==null) { + detail = new String[1]; + } else { + int l = result.variables.length; + detail=new String[l+1]; + System.arraycopy(result.variables, 0, detail, 1, l); + } + error(trans, response, result.status,msg,detail); + } + + @Override + public void error(AuthzTrans trans, HttpServletResponse response, int status, String msg, String ... _detail) { + String[] detail = _detail; + if(detail.length==0) { + detail=new String[1]; + } + boolean hidemsg = false; + String msgId; + switch(status) { + case 202: + case ERR_ActionNotCompleted: + msgId = "SVC1202"; + detail[0] = "Accepted, Action not complete"; + response.setStatus(/*httpstatus=*/202); + break; + + case 403: + case ERR_Policy: + case ERR_Security: + case ERR_Denied: + msgId = "SVC1403"; + detail[0] = "Forbidden"; + response.setStatus(/*httpstatus=*/403); + break; + + case 404: + case ERR_NotFound: + msgId = "SVC1404"; + detail[0] = "Not Found"; + response.setStatus(/*httpstatus=*/404); + break; + + case 406: + case ERR_BadData: + msgId="SVC1406"; + detail[0] = "Not Acceptable"; + response.setStatus(/*httpstatus=*/406); + break; + + case 409: + case ERR_ConflictAlreadyExists: + msgId = "SVC1409"; + detail[0] = "Conflict Already Exists"; + response.setStatus(/*httpstatus=*/409); + break; + + case 501: + case ERR_NotImplemented: + msgId = "SVC1501"; + detail[0] = "Not Implemented"; + response.setStatus(/*httpstatus=*/501); + break; + + default: + msgId = "SVC1500"; + detail[0] = "General Service Error"; + response.setStatus(/*httpstatus=*/500); + hidemsg = true; + break; + } + + try { + StringBuilder holder = new StringBuilder(); + ERROR em = mapper().errorFromMessage(holder,msgId,msg,detail); + trans.checkpoint( + "ErrResp [" + + msgId + + "] " + + holder.toString(), + Env.ALWAYS); + if(hidemsg) { + holder.setLength(0); + em = mapper().errorFromMessage(holder, msgId, "Server had an issue processing this request"); + } + errDF.newData(trans).load(em).to(response.getOutputStream()); + + } catch (Exception e) { + trans.error().log(e,"unable to send response for",msg); + } + } + + /* (non-Javadoc) + * @see com.att.authz.facade.AuthzFacade#getAPI(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletResponse) + */ + public final static String API_REPORT = "apiReport"; + @Override + public Result getAPI(AuthzTrans trans, HttpServletResponse resp, RServlet rservlet) { + TimeTaken tt = trans.start(API_REPORT, Env.SUB); + try { + Api api = new Api(); + Api.Route ar; + Method[] meths = LocateServiceImpl.class.getDeclaredMethods(); + for(RouteReport rr : rservlet.routeReport()) { + api.getRoute().add(ar = new Api.Route()); + ar.setMeth(rr.meth.name()); + ar.setPath(rr.path); + ar.setDesc(rr.desc); + ar.getContentType().addAll(rr.contextTypes); + for(Method m : meths) { + ApiDoc ad; + if((ad = m.getAnnotation(ApiDoc.class))!=null && + rr.meth.equals(ad.method()) && + rr.path.equals(ad.path())) { + for(String param : ad.params()) { + ar.getParam().add(param); + } + for(String text : ad.text()) { + ar.getComments().add(text); + } + ar.setExpected(ad.expectedCode()); + for(int ec : ad.errorCodes()) { + ar.getExplicitErr().add(ec); + } + } + } + } + apiDF.newData(trans).load(api).to(resp.getOutputStream()); + setContentType(resp,apiDF.getOutType()); + return Result.ok(); + + } catch (Exception e) { + trans.error().log(e,IN,API_REPORT); + return Result.err(e); + } finally { + tt.done(); + } + } + + public final static String API_EXAMPLE = "apiExample"; + /* (non-Javadoc) + * @see com.att.authz.facade.AuthzFacade#getAPIExample(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String) + */ + @Override + public Result getAPIExample(AuthzTrans trans, HttpServletResponse resp, String nameOrContentType, boolean optional) { + TimeTaken tt = trans.start(API_EXAMPLE, Env.SUB); + try { + String content =Examples.print(apiDF.getEnv(), nameOrContentType, optional); + resp.getOutputStream().print(content); + setContentType(resp,content.contains(" getEndpoints(AuthzTrans trans, HttpServletResponse resp, String key, String service, String version, String other) { + TimeTaken tt = trans.start(GET_ENDPOINTS, Env.SUB); + try { + String output=null; + long temp=System.currentTimeMillis(); + synchronized(GET_ENDPOINTS) { + if(cacheClear reps = this.service.getEndPoints(trans,service,version,other); + if(reps.notOK()) { + return Result.err(reps); + } else { + output = epDF.newData(trans).load(reps.value).asString(); + synchronized(GET_ENDPOINTS) { + epsCache.put(key, output); + } + } + } + resp.getOutputStream().println(output); + setContentType(resp,epDF.getOutType()); + return Result.ok(); + } catch (Exception e) { + trans.error().log(e,IN,API_EXAMPLE); + return Result.err(Result.ERR_NotImplemented,e.getMessage()); + } finally { + tt.done(); + } + } + + private static final String PUT_MGMT_ENDPOINTS = "Put Mgmt Endpoints"; + /* (non-Javadoc) + * @see org.onap.aaf.auth.locate.facade.GwFacade#putMgmtEndpoints(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + @Override + public Result putMgmtEndpoints(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) { + TimeTaken tt = trans.start(PUT_MGMT_ENDPOINTS, Env.SUB|Env.ALWAYS); + try { + MGMT_ENDPOINTS rreq; + try { + RosettaData data = mepDF.newData().load(req.getInputStream()); + rreq = data.asObject(); + } catch(APIException e) { + trans.error().log("Invalid Input",IN,PUT_MGMT_ENDPOINTS); + return Result.err(Status.ERR_BadData,"Invalid Input"); + + } + Result rp = service.putMgmtEndPoints(trans, rreq); + switch(rp.status) { + case OK: + synchronized(GET_ENDPOINTS) { + cacheClear = 0L; + } + setContentType(resp,mepDF.getOutType()); + return Result.ok(); + default: + return rp; + } + } catch (Exception e) { + trans.error().log(e,IN,PUT_MGMT_ENDPOINTS); + return Result.err(e); + } finally { + tt.done(); + } + } + + private static final String DELETE_MGMT_ENDPOINTS = "Delete Mgmt Endpoints"; + /* (non-Javadoc) + * @see org.onap.aaf.auth.locate.facade.GwFacade#removeMgmtEndpoints(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + @Override + public Result removeMgmtEndpoints(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) { + TimeTaken tt = trans.start(DELETE_MGMT_ENDPOINTS, Env.SUB|Env.ALWAYS); + try { + MGMT_ENDPOINTS rreq; + try { + RosettaData data = mepDF.newData().load(req.getInputStream()); + rreq = data.asObject(); + } catch(APIException e) { + trans.error().log("Invalid Input",IN,DELETE_MGMT_ENDPOINTS); + return Result.err(Status.ERR_BadData,"Invalid Input"); + + } + Result rp = service.removeMgmtEndPoints(trans, rreq); + switch(rp.status) { + case OK: + synchronized(GET_ENDPOINTS) { + cacheClear = 0L; + } + setContentType(resp,mepDF.getOutType()); + return Result.ok(); + default: + return rp; + } + } catch (Exception e) { + trans.error().log(e,IN,DELETE_MGMT_ENDPOINTS); + return Result.err(e); + } finally { + tt.done(); + } + } + +} \ No newline at end of file