Extract class StopWatch from ApiService

Issue-ID: DMAAP-1109

Change-Id: I05f706b8f2e7fe0ceb632ddb008c897b32f576b2
Signed-off-by: Pawel <pawel.kasperkiewicz@nokia.com>
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.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 ApiPolicy apiPolicy;
 
-	 private String apiNamespace;
+    public ApiService() {
 
-	 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() {
+        err = new ApiError();
+        requestId = (new RandomString(10)).nextString();
 
-		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();
+        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);	
-	}
+        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 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;
-	}
+    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() );
-	}
+    // 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 setCode(int statusCode) {
+        err.setCode(statusCode);
+    }
 
 
-	public void setMessage(String string) {
-		err.setMessage(string);
-	}
+    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 setFields(String string) {
+        err.setFields(string);
+    }
 
-	
-	public void checkAuthorization() throws AuthenticationErrorException, Exception {
+    public void checkAuthorization(String auth, String uriPath, String httpMethod)
+        throws AuthenticationErrorException, Exception {
+        authorization = auth;
+        setUriFromPath(uriPath);
+        method = httpMethod;
 
-		MDC.put(MDC_KEY_REQUEST_ID, requestId); 
-	
-		logger.info("request: uri={} method={} auth={}", uri, method, authorization );
+        checkAuthorization();
+    }
 
-		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();
+
+    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;
+        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;
-	}
+        }
+
+
+    }
+
+    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