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