2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 
   6  * ================================================================================
 
   7  * Copyright (C) 2017 Amdocs
 
   8  * =============================================================================
 
   9  * Licensed under the Apache License, Version 2.0 (the "License");
 
  10  * you may not use this file except in compliance with the License.
 
  11  * You may obtain a copy of the License at
 
  13  *      http://www.apache.org/licenses/LICENSE-2.0
 
  15  * Unless required by applicable law or agreed to in writing, software
 
  16  * distributed under the License is distributed on an "AS IS" BASIS,
 
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  18  * See the License for the specific language governing permissions and
 
  19  * limitations under the License.
 
  21  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
 
  22  * ============LICENSE_END=========================================================
 
  27 package org.onap.appc.adapter.rest.impl;
 
  29 import org.onap.appc.Constants;
 
  30 import org.onap.appc.configuration.Configuration;
 
  31 import org.onap.appc.configuration.ConfigurationFactory;
 
  32 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
 
  35  * This class is used to track and maintain recovery and time-to-live information for a request as it is being
 
  38 public class RequestContext {
 
  40      * The number of seconds of wait time between successive attempts to connect to the provider. This is used to
 
  41      * recover from provider outages or failures. It is not used to recover from logical errors, such as an invalid
 
  42      * request, server not found, etc.
 
  44     private Integer retryDelay;
 
  47      * The number of times we will attempt to connect to the provider. This is used to recover from provider outages or
 
  48      * failures. It is not used to recover from logical errors, such as an invalid request, server not found, etc.
 
  50     private Integer retryLimit;
 
  53      * The total time, in milliseconds, that the provider can have to process this request. If the accumulated time
 
  54      * exceeds the time to live, then the request is failed with a timeout exception, regardless of the state of the
 
  55      * provider. Note that the caller may supply this as a value in seconds, in which case it must be converted to
 
  56      * milliseconds for the request context.
 
  58     private Long timeToLive;
 
  61      * The accumulated time, in milliseconds, that has been used so far to process the request. This is compared to the
 
  62      * time to live each time it is updated. If the accumulated time exceeds the time to live, then the request is
 
  63      * failed with a timeout exception, regardless of the state of the provider.
 
  65     private long accumulatedTime;
 
  68      * The total number of retries attempted so far
 
  73      * The time when the stopwatch was started
 
  75     private long startTime = -1;
 
  78      * The service logic (DG) context from the SLI
 
  80     private SvcLogicContext svcLogicContext;
 
  85     private Configuration configuration = ConfigurationFactory.getConfiguration();
 
  88      * Set to true whenever the retry limit has been exceeded, reset to false when reset() is called.
 
  90     private boolean retryFailed;
 
  93      * Creates the request context
 
  96      *            The service logic (SLI) context associated with the current DG
 
  98     public RequestContext(SvcLogicContext context) {
 
  99         setSvcLogicContext(context);
 
 103      * @return The retry delay, in seconds. If zero, then no retry is to be performed
 
 105     public int getRetryDelay() {
 
 106         if (retryDelay == null) {
 
 107             int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_DELAY);
 
 108             retryDelay = Integer.valueOf(value);
 
 111         return retryDelay.intValue();
 
 115      * This method is a helper that allows the caller to delay for the retry interval time and not have to handle the
 
 116      * thread interruption, timer handling, etc.
 
 118     public void delay() {
 
 119         long time = getRetryDelay() * 1000L;
 
 120         long future = System.currentTimeMillis() + time;
 
 122             while (System.currentTimeMillis() < future && time > 0) {
 
 125                 } catch (InterruptedException e) {
 
 127                      * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that
 
 128                      * case, the thread is resumed before the delay time has actually expired, so re-calculate the
 
 129                      * amount of delay time needed and reenter the sleep until we get to the future time.
 
 131                     time = future - System.currentTimeMillis();
 
 138      * @return The number of retries that are allowed per connection
 
 140     public int getRetryLimit() {
 
 141         if (retryLimit == null) {
 
 142             int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_LIMIT);
 
 143             retryLimit = Integer.valueOf(value);
 
 146         return retryLimit.intValue();
 
 150      * Check and count the connection attempt.
 
 152      * @return True if the connection should be attempted. False indicates that the number of retries has been exhausted
 
 153      *         and it should NOT be attempted.
 
 155     public boolean attempt() {
 
 156         if (retryFailed || attempt >= getRetryLimit()) {
 
 166      * @return The number of retry attempts so far
 
 168     public int getAttempts() {
 
 173      * @return True if the retry limit has been exceeded, false otherwise
 
 175     public boolean isFailed() {
 
 180      * This method both checks the time to live to see if it has been exceeded and accumulates the total time used so
 
 183      * Each time this method is called it accumulates the total duration since the last time it was called to the total
 
 184      * time accumulator. It then checks the total time to the time to live and if greater, it returns false. As long as
 
 185      * the total time used is less than or equal to the time to live limit, the method returns true. It is important to
 
 186      * call this method at the very beginning of the process so that all parts of the process are tracked.
 
 189      * @return True if the total time to live has not been exceeded. False indicates that the total time to live has
 
 190      *         been exceeded and no further processing should be performed.
 
 192     public boolean isAlive() {
 
 193         long now = System.currentTimeMillis();
 
 194         if (startTime == -1) {
 
 198         accumulatedTime += (now - startTime);
 
 200         if (accumulatedTime > timeToLive) {
 
 207      * @return The total amount of time used, in milliseconds.
 
 209     public long getTotalDuration() {
 
 210         return accumulatedTime;
 
 214      * This method is called to reset the retry counters. It has no effect on the time to live accumulator.
 
 216     public void reset() {
 
 221      * Sets the time to live to the value, expressed in seconds
 
 224      *            The time to live, in seconds
 
 226     public void setTimeToLiveSeconds(int time) {
 
 227         setTimeToLiveMS(time * 1000L);
 
 231      * Sets the time to live to the value, expressed in milliseconds
 
 234      *            The time to live, in milliseconds
 
 236     public void setTimeToLiveMS(long time) {
 
 237         this.timeToLive = time;
 
 241      * @return The service logic context associated with this request
 
 243     public SvcLogicContext getSvcLogicContext() {
 
 244         return svcLogicContext;
 
 248      * @param svcLogicContext
 
 249      *            The service logic context to be associated with this request
 
 251     public void setSvcLogicContext(SvcLogicContext svcLogicContext) {
 
 252         this.svcLogicContext = svcLogicContext;