From: Pawel Date: Thu, 21 Mar 2019 09:33:21 +0000 (-0400) Subject: Extract class StopWatch from ApiService X-Git-Tag: 1.0.26~30^2~1 X-Git-Url: https://gerrit.onap.org/r/gitweb?p=dmaap%2Fdbcapi.git;a=commitdiff_plain;h=44cc0755f83283b7666ad8e2da68c14758bebf08 Extract class StopWatch from ApiService Issue-ID: DMAAP-1109 Change-Id: I05f706b8f2e7fe0ceb632ddb008c897b32f576b2 Signed-off-by: Pawel --- diff --git a/src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java b/src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java index 23f4fef..b2eee6f 100644 --- a/src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java +++ b/src/main/java/org/onap/dmaap/dbcapi/service/ApiService.java @@ -7,9 +7,9 @@ * 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. @@ -20,22 +20,14 @@ package org.onap.dmaap.dbcapi.service; -import static com.att.eelf.configuration.Configuration.MDC_BEGIN_TIMESTAMP; -import static com.att.eelf.configuration.Configuration.MDC_ELAPSED_TIME; -import static com.att.eelf.configuration.Configuration.MDC_END_TIMESTAMP; import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID; import static com.att.eelf.configuration.Configuration.MDC_PARTNER_NAME; import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; - import javax.ws.rs.core.Response.Status; import javax.xml.bind.DatatypeConverter; - import org.onap.dmaap.dbcapi.aaf.DmaapPerm; import org.onap.dmaap.dbcapi.authentication.ApiPolicy; import org.onap.dmaap.dbcapi.authentication.AuthenticationErrorException; @@ -48,233 +40,199 @@ import org.onap.dmaap.dbcapi.util.RandomString; import org.slf4j.MDC; public class ApiService extends BaseLoggingClass { - private class StopWatch { - private long clock = 0; - private long elapsed = 0; - - - - public StopWatch() { - clock = 0; - elapsed = 0; - } - - public void reset() { - clock = System.currentTimeMillis(); - elapsed = 0; - } - public void stop() { - Long stopTime = System.currentTimeMillis(); - elapsed += stopTime - clock; - clock = 0; - MDC.put( MDC_END_TIMESTAMP, isoFormatter.format(new Date(stopTime))); - MDC.put( MDC_ELAPSED_TIME, String.valueOf(elapsed)); - } - public void start() { - if ( clock != 0 ) { - //not stopped - return; - } - clock = System.currentTimeMillis(); - MDC.put( MDC_BEGIN_TIMESTAMP, isoFormatter.format(new Date(clock))); - } - private long getElapsed() { - return elapsed; - } - } - - private String apiNamespace; - - private String uri; - private String uriPath; - private String method; - private String authorization; - private String requestId; - private ApiError err; - private StopWatch stopwatch; - private ApiPolicy apiPolicy; - - public static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; - public final static TimeZone utc = TimeZone.getTimeZone("UTC"); - public final static SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT); - - static { - isoFormatter.setTimeZone(utc); - } - public ApiService() { - - stopwatch = new StopWatch(); - stopwatch.start(); - err = new ApiError(); - requestId = (new RandomString(10)).nextString(); - - if (apiNamespace == null) { - DmaapConfig p = (DmaapConfig)DmaapConfig.getConfig(); - apiNamespace = p.getProperty("ApiNamespace", "org.openecomp.dmaapBC.api"); - logger.info( "config param usePE has been deprecated. Use ApiPermission.Class property instead."); - } - apiPolicy = new ApiPolicy(); - - logger.info( "apiNamespace=" + apiNamespace); - } - - public ApiService setAuth( String auth ) { - this.authorization = auth; - logger.info( "setAuth: authorization={} ", authorization); - return this; - } - private void setServiceName(){ - String svcRequest = new String( this.method + " " + this.uriPath ); - MDC.put(MDC_SERVICE_NAME, svcRequest ); - } - public ApiService setHttpMethod( String httpMethod ) { - this.method = httpMethod; - logger.info( "setHttpMethod: method={} ", method); - setServiceName(); - return this; - } - public ApiService setUriPath( String uriPath ) { - this.uriPath = uriPath; - this.uri = setUriFromPath( uriPath ); - logger.info( "setUriPath: uriPath={} uri={}", uriPath, uri); - setServiceName(); - return this; - } - private String setUriFromPath( String uriPath ) { - int ch = uriPath.indexOf("/"); - if ( ch > 0 ) { - return( (String) uriPath.subSequence(0, ch ) ); - } else { - return uriPath; - } - } - - public ApiError getErr() { - return err; - } - - - public void setErr(ApiError err) { - this.err = err; - } - - - // test for presence of a required field - public void required( String name, Object val, String expr ) throws RequiredFieldException { - err.setCode(0); - if ( val == null ) { - err.setCode(Status.BAD_REQUEST.getStatusCode()); - err.setMessage("missing required field"); - err.setFields( name ); - throw new RequiredFieldException(); - } - if ( expr != null && ! expr.isEmpty() ) { - Pattern pattern = Pattern.compile(expr); - Matcher matcher = pattern.matcher((CharSequence) val); - if ( ! matcher.find() ) { - err.setCode(Status.BAD_REQUEST.getStatusCode()); - err.setMessage( "value '" + val + "' violates regexp check '" + expr + "'"); - err.setFields( name ); - throw new RequiredFieldException(); - } - } - } - - // utility to serialize ApiErr object - public String toString() { - return String.format( "code=%d msg=%s fields=%s", err.getCode(), err.getMessage(), err.getFields() ); - } - - - public void setCode(int statusCode) { - err.setCode(statusCode); - } - - - public void setMessage(String string) { - err.setMessage(string); - } - - - public void setFields(String string) { - err.setFields(string); - } - - public void checkAuthorization( String auth, String uriPath, String httpMethod ) throws AuthenticationErrorException, Exception { - authorization = auth; - setUriFromPath( uriPath ); - method = httpMethod; - - checkAuthorization(); - } - - - public void checkAuthorization() throws AuthenticationErrorException, Exception { - - MDC.put(MDC_KEY_REQUEST_ID, requestId); - - logger.info("request: uri={} method={} auth={}", uri, method, authorization ); - - if ( uri == null || uri.isEmpty()) { - String errmsg = "No URI value provided "; - err.setMessage(errmsg); - logger.info( errmsg ); - throw new AuthenticationErrorException( ); - } - if ( method == null || method.isEmpty()) { - String errmsg = "No method value provided "; - err.setMessage(errmsg); - logger.info( errmsg ); - throw new AuthenticationErrorException( ); - } - DmaapService dmaapService = new DmaapService(); - Dmaap dmaap = dmaapService.getDmaap(); - String env = dmaap.getDmaapName(); - - // special case during bootstrap of app when DMaaP environment may not be set. - // this allows us to authorize certain APIs used for initialization during this window. - if ( env == null || env.isEmpty() ) { - env = "boot"; - } - if ( ! apiPolicy.getUseAuthClass() ) return; // skip authorization if not enabled - if ( authorization == null || authorization.isEmpty()) { - String errmsg = "No basic authorization value provided "; - err.setMessage(errmsg); - logger.info( errmsg ); - throw new AuthenticationErrorException( ); - } - String credentials = authorization.substring("Basic".length()).trim(); + + private String apiNamespace; + private String uri; + private String uriPath; + private String method; + private String authorization; + private String requestId; + private ApiError err; + private ApiPolicy apiPolicy; + + public ApiService() { + + err = new ApiError(); + requestId = (new RandomString(10)).nextString(); + + if (apiNamespace == null) { + DmaapConfig p = (DmaapConfig) DmaapConfig.getConfig(); + apiNamespace = p.getProperty("ApiNamespace", "org.openecomp.dmaapBC.api"); + logger.info("config param usePE has been deprecated. Use ApiPermission.Class property instead."); + } + apiPolicy = new ApiPolicy(); + + logger.info("apiNamespace=" + apiNamespace); + } + + public ApiService setAuth(String auth) { + this.authorization = auth; + logger.info("setAuth: authorization={} ", authorization); + return this; + } + + private void setServiceName() { + String svcRequest = new String(this.method + " " + this.uriPath); + MDC.put(MDC_SERVICE_NAME, svcRequest); + } + + public ApiService setHttpMethod(String httpMethod) { + this.method = httpMethod; + logger.info("setHttpMethod: method={} ", method); + setServiceName(); + return this; + } + + public ApiService setUriPath(String uriPath) { + this.uriPath = uriPath; + this.uri = setUriFromPath(uriPath); + logger.info("setUriPath: uriPath={} uri={}", uriPath, uri); + setServiceName(); + return this; + } + + private String setUriFromPath(String uriPath) { + int ch = uriPath.indexOf("/"); + if (ch > 0) { + return ((String) uriPath.subSequence(0, ch)); + } else { + return uriPath; + } + } + + public ApiError getErr() { + return err; + } + + + public void setErr(ApiError err) { + this.err = err; + } + + + // test for presence of a required field + public void required(String name, Object val, String expr) throws RequiredFieldException { + err.setCode(0); + if (val == null) { + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage("missing required field"); + err.setFields(name); + throw new RequiredFieldException(); + } + if (expr != null && !expr.isEmpty()) { + Pattern pattern = Pattern.compile(expr); + Matcher matcher = pattern.matcher((CharSequence) val); + if (!matcher.find()) { + err.setCode(Status.BAD_REQUEST.getStatusCode()); + err.setMessage("value '" + val + "' violates regexp check '" + expr + "'"); + err.setFields(name); + throw new RequiredFieldException(); + } + } + } + + // utility to serialize ApiErr object + public String toString() { + return String.format("code=%d msg=%s fields=%s", err.getCode(), err.getMessage(), err.getFields()); + } + + + public void setCode(int statusCode) { + err.setCode(statusCode); + } + + + public void setMessage(String string) { + err.setMessage(string); + } + + + public void setFields(String string) { + err.setFields(string); + } + + public void checkAuthorization(String auth, String uriPath, String httpMethod) + throws AuthenticationErrorException, Exception { + authorization = auth; + setUriFromPath(uriPath); + method = httpMethod; + + checkAuthorization(); + } + + + public void checkAuthorization() throws AuthenticationErrorException, Exception { + + MDC.put(MDC_KEY_REQUEST_ID, requestId); + + logger.info("request: uri={} method={} auth={}", uri, method, authorization); + + if (uri == null || uri.isEmpty()) { + String errmsg = "No URI value provided "; + err.setMessage(errmsg); + logger.info(errmsg); + throw new AuthenticationErrorException(); + } + if (method == null || method.isEmpty()) { + String errmsg = "No method value provided "; + err.setMessage(errmsg); + logger.info(errmsg); + throw new AuthenticationErrorException(); + } + DmaapService dmaapService = new DmaapService(); + Dmaap dmaap = dmaapService.getDmaap(); + String env = dmaap.getDmaapName(); + + // special case during bootstrap of app when DMaaP environment may not be set. + // this allows us to authorize certain APIs used for initialization during this window. + if (env == null || env.isEmpty()) { + env = "boot"; + } + if (!apiPolicy.getUseAuthClass()) { + return; // skip authorization if not enabled + } + if (authorization == null || authorization.isEmpty()) { + String errmsg = "No basic authorization value provided "; + err.setMessage(errmsg); + logger.info(errmsg); + throw new AuthenticationErrorException(); + } + String credentials = authorization.substring("Basic".length()).trim(); byte[] decoded = DatatypeConverter.parseBase64Binary(credentials); String decodedString = new String(decoded); String[] actualCredentials = decodedString.split(":"); String ID = actualCredentials[0]; String Password = actualCredentials[1]; MDC.put(MDC_PARTNER_NAME, ID); - try { - - DmaapPerm p = new DmaapPerm( apiNamespace + "." + uri, env, method ); - apiPolicy.check( ID, Password, p); - } catch ( AuthenticationErrorException ae ) { - String errmsg = "User " + ID + " failed authentication/authorization for " + apiNamespace + "." + uriPath + " " + env + " " + method; - logger.info( errmsg ); - err.setMessage(errmsg); - throw ae; - - } - - - } - public String getRequestId() { - return requestId; - } - public ApiService setRequestId(String requestId) { - if ( requestId == null || requestId.isEmpty()) { - this.requestId = (new RandomString(10)).nextString(); - logger.warn( "X-ECOMP-RequestID not set in HTTP Header. Setting RequestId value to: " + this.requestId ); - } else { - this.requestId = requestId; - } - MDC.put(MDC_KEY_REQUEST_ID, this.requestId); - return this; - } + try { + + DmaapPerm p = new DmaapPerm(apiNamespace + "." + uri, env, method); + apiPolicy.check(ID, Password, p); + } catch (AuthenticationErrorException ae) { + String errmsg = + "User " + ID + " failed authentication/authorization for " + apiNamespace + "." + uriPath + " " + env + + " " + method; + logger.info(errmsg); + err.setMessage(errmsg); + throw ae; + + } + + + } + + public String getRequestId() { + return requestId; + } + + public ApiService setRequestId(String requestId) { + if (requestId == null || requestId.isEmpty()) { + this.requestId = (new RandomString(10)).nextString(); + logger.warn("X-ECOMP-RequestID not set in HTTP Header. Setting RequestId value to: " + this.requestId); + } else { + this.requestId = requestId; + } + MDC.put(MDC_KEY_REQUEST_ID, this.requestId); + return this; + } } diff --git a/src/main/java/org/onap/dmaap/dbcapi/service/StopWatch.java b/src/main/java/org/onap/dmaap/dbcapi/service/StopWatch.java new file mode 100644 index 0000000..6dc8fe9 --- /dev/null +++ b/src/main/java/org/onap/dmaap/dbcapi/service/StopWatch.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.dmaap + * ================================================================================ + * Copyright (C) 2019 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.dmaap.dbcapi.service; + +import static com.att.eelf.configuration.Configuration.MDC_BEGIN_TIMESTAMP; +import static com.att.eelf.configuration.Configuration.MDC_ELAPSED_TIME; +import static com.att.eelf.configuration.Configuration.MDC_END_TIMESTAMP; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; +import org.slf4j.MDC; + + +public class StopWatch { + + private static final String ISO_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + private final static SimpleDateFormat isoFormatter = new SimpleDateFormat(ISO_FORMAT); + private final static TimeZone utc = TimeZone.getTimeZone("UTC"); + + private long startTimestamp; + private long elapsedTime; + + static { + isoFormatter.setTimeZone(utc); + } + + public void start() { + startTimestamp = System.currentTimeMillis(); + MDC.put(MDC_BEGIN_TIMESTAMP, isoFormatter.format(new Date(startTimestamp))); + } + + public void stop() { + long endTimestamp = System.currentTimeMillis(); + elapsedTime = endTimestamp - startTimestamp; + MDC.put(MDC_END_TIMESTAMP, isoFormatter.format(new Date(endTimestamp))); + MDC.put(MDC_ELAPSED_TIME, String.valueOf(elapsedTime)); + } + + public void resetElapsedTime() { + elapsedTime = 0; + } + + public long getElapsedTime() { + return elapsedTime; + } +} diff --git a/src/test/java/org/onap/dmaap/dbcapi/service/StopWatchTest.java b/src/test/java/org/onap/dmaap/dbcapi/service/StopWatchTest.java new file mode 100644 index 0000000..b4b6af2 --- /dev/null +++ b/src/test/java/org/onap/dmaap/dbcapi/service/StopWatchTest.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * org.onap.dmaap + * ================================================================================ + * Copyright (C) 2019 Nokia 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.dmaap.dbcapi.service; + +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import org.junit.Test; +import org.onap.dmaap.dbcapi.logging.BaseLoggingClass; + +public class StopWatchTest extends BaseLoggingClass { + + private StopWatch stopWatch = new StopWatch(); + + @Test + public void stopWatchShouldReturnElapsedTime() throws InterruptedException { + stopWatch.start(); + Thread.sleep(50); + stopWatch.stop(); + assertTrue(stopWatch.getElapsedTime() > 0); + } + + @Test + public void resetShouldSetElapsedTime() { + stopWatch.start(); + stopWatch.stop(); + stopWatch.resetElapsedTime(); + assertEquals(0,stopWatch.getElapsedTime()); + + } + +} \ No newline at end of file