Merge of new rebased code
[appc.git] / appc-adapters / appc-rest-healthcheck-adapter / appc-rest-healthcheck-adapter-bundle / src / main / java / org / openecomp / appc / adapter / restHealthcheck / impl / RequestContext.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : APP-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22
23
24 package org.openecomp.appc.adapter.restHealthcheck.impl;
25
26 import org.openecomp.appc.Constants;
27 import org.openecomp.appc.configuration.Configuration;
28 import org.openecomp.sdnc.sli.SvcLogicContext;
29
30 public class RequestContext {
31     /**
32      * The number of seconds of wait time between successive attempts to connect to the provider. This is used to
33      * recover from provider outages or failures. It is not used to recover from logical errors, such as an invalid
34      * request, server not found, etc.
35      */
36     private Integer retryDelay;
37
38     /**
39      * The number of times we will attempt to connect to the provider. This is used to recover from provider outages or
40      * failures. It is not used to recover from logical errors, such as an invalid request, server not found, etc.
41      */
42     private Integer retryLimit;
43
44     /**
45      * The total time, in milliseconds, that the provider can have to process this request. If the accumulated time
46      * exceeds the time to live, then the request is failed with a timeout exception, regardless of the state of the
47      * provider. Note that the caller may supply this as a value in seconds, in which case it must be converted to
48      * milliseconds for the request context.
49      */
50     private Long timeToLive;
51
52     /**
53      * The accumulated time, in milliseconds, that has been used so far to process the request. This is compared to the
54      * time to live each time it is updated. If the accumulated time exceeds the time to live, then the request is
55      * failed with a timeout exception, regardless of the state of the provider.
56      */
57     private long accumulatedTime;
58
59     /**
60      * The total number of retries attempted so far
61      */
62     private int attempt;
63
64     /**
65      * The time when the stopwatch was started
66      */
67     private long startTime = -1;
68
69     /**
70      * The service logic (DG) context from the SLI
71      */
72     private SvcLogicContext svcLogicContext;
73
74     /**
75      * The configuration
76      */
77
78
79     /**
80      * Set to true whenever the retry limit has been exceeded, reset to false when reset() is called.
81      */
82     private boolean retryFailed;
83
84     /**
85      * Creates the request context
86      * 
87      * @param context
88      *            The service logic (SLI) context associated with the current DG
89      */
90     public RequestContext(SvcLogicContext context) {
91         setSvcLogicContext(context);
92     }
93
94     /**
95      * @return The retry delay, in seconds. If zero, then no retry is to be performed
96      */
97     public int getRetryDelay() {
98         if (retryDelay == null) {
99             int value = 10;
100             retryDelay = Integer.valueOf(value);
101         }
102
103         return retryDelay.intValue();
104     }
105
106     /**
107      * This method is a helper that allows the caller to delay for the retry interval time and not have to handle the
108      * thread interruption, timer handling, etc.
109      */
110     public void delay() {
111         long time = getRetryDelay() * 1000L;
112         long future = System.currentTimeMillis() + time;
113         if (time != 0) {
114             while (System.currentTimeMillis() < future && time > 0) {
115                 try {
116                     Thread.sleep(time);
117                 } catch (InterruptedException e) {
118                     /*
119                      * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that
120                      * case, the thread is resumed before the delay time has actually expired, so re-calculate the
121                      * amount of delay time needed and reenter the sleep until we get to the future time.
122                      */
123                     time = future - System.currentTimeMillis();
124                 }
125             }
126         }
127     }
128
129     /**
130      * @return The number of retries that are allowed per connection
131      */
132     public int getRetryLimit() {
133         if (retryLimit == null) {
134             int value = 10;
135             retryLimit = Integer.valueOf(value);
136         }
137
138         return retryLimit.intValue();
139     }
140
141     /**
142      * Check and count the connection attempt.
143      * 
144      * @return True if the connection should be attempted. False indicates that the number of retries has been exhausted
145      *         and it should NOT be attempted.
146      */
147     public boolean attempt() {
148         if (retryFailed || attempt >= getRetryLimit()) {
149             retryFailed = true;
150             return false;
151         }
152         attempt++;
153
154         return true;
155     }
156
157     /**
158      * @return The number of retry attempts so far
159      */
160     public int getAttempts() {
161         return attempt;
162     }
163
164     /**
165      * @return True if the retry limit has been exceeded, false otherwise
166      */
167     public boolean isFailed() {
168         return retryFailed;
169     }
170
171     /**
172      * This method both checks the time to live to see if it has been exceeded and accumulates the total time used so
173      * far.
174      * <p>
175      * Each time this method is called it accumulates the total duration since the last time it was called to the total
176      * time accumulator. It then checks the total time to the time to live and if greater, it returns false. As long as
177      * the total time used is less than or equal to the time to live limit, the method returns true. It is important to
178      * call this method at the very beginning of the process so that all parts of the process are tracked.
179      * </p>
180      * 
181      * @return True if the total time to live has not been exceeded. False indicates that the total time to live has
182      *         been exceeded and no further processing should be performed.
183      */
184     public boolean isAlive() {
185         long now = System.currentTimeMillis();
186         if (startTime == -1) {
187             startTime = now;
188             return true;
189         }
190         accumulatedTime += (now - startTime);
191         startTime = now;
192         if (accumulatedTime > timeToLive) {
193             return false;
194         }
195         return true;
196     }
197
198     /**
199      * @return The total amount of time used, in milliseconds.
200      */
201     public long getTotalDuration() {
202         return accumulatedTime;
203     }
204
205     /**
206      * This method is called to reset the retry counters. It has no effect on the time to live accumulator.
207      */
208     public void reset() {
209         attempt = 0;
210     }
211
212     /**
213      * Sets the time to live to the value, expressed in seconds
214      * 
215      * @param time
216      *            The time to live, in seconds
217      */
218     public void setTimeToLiveSeconds(int time) {
219         setTimeToLiveMS(time * 1000L);
220     }
221
222     /**
223      * Sets the time to live to the value, expressed in milliseconds
224      * 
225      * @param time
226      *            The time to live, in milliseconds
227      */
228     public void setTimeToLiveMS(long time) {
229         this.timeToLive = time;
230     }
231
232     /**
233      * @return The service logic context associated with this request
234      */
235     public SvcLogicContext getSvcLogicContext() {
236         return svcLogicContext;
237     }
238
239     /**
240      * @param svcLogicContext
241      *            The service logic context to be associated with this request
242      */
243     public void setSvcLogicContext(SvcLogicContext svcLogicContext) {
244         this.svcLogicContext = svcLogicContext;
245     }
246 }