7b886d682a84548f6b87d2d51f73a1c59711ece3
[msb/java-sdk.git] / src / main / java / org / onap / msb / sdk / httpclient / handler / RetrofitServiceHandler.java
1 /*******************************************************************************
2  * Copyright 2017 ZTE, Inc. and others.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  * 
7  * http://www.apache.org/licenses/LICENSE-2.0
8  * 
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  ******************************************************************************/
14 /**
15  * 
16  */
17 package org.onap.msb.sdk.httpclient.handler;
18
19 import java.lang.reflect.InvocationHandler;
20 import java.lang.reflect.Method;
21 import java.util.Map;
22 import java.util.concurrent.atomic.AtomicReference;
23
24 import org.onap.msb.sdk.httpclient.ProxyRetrofitCall;
25 import org.onap.msb.sdk.httpclient.ServiceHttpEndPointObject;
26 import org.onap.msb.sdk.httpclient.exception.RetrofitServiceRuntimeException;
27 import org.onap.msb.sdk.httpclient.lb.LoadBalanceContext;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import jersey.repackaged.com.google.common.collect.Lists;
32 import retrofit2.Call;
33
34 /**
35  * @author 10071214
36  *
37  */
38 public class RetrofitServiceHandler implements InvocationHandler {
39
40   private final static Logger logger = LoggerFactory.getLogger(RetrofitServiceHandler.class);
41   private static long periodTime = 60;
42
43   static {
44     try {
45       String periodStr = System.getenv("retrofit_route_cache_refresh_period");
46       periodTime = periodStr != null ? Long.valueOf(periodStr) : 60;
47       logger.info("retrofit_route_cache_refresh_period:" + periodTime);
48     } catch (Exception e) {
49       logger.warn("", e);
50     }
51
52   }
53
54
55
56   private RetrofitServiceHandlerContext flowContext;
57
58   private AtomicReference<Map<ServiceHttpEndPointObject, Object>> endPointToRetrofitRef =
59       new AtomicReference();
60
61   public RetrofitServiceHandler(RetrofitServiceHandlerContext flowContext) {
62     super();
63     this.flowContext = flowContext;
64     logger.info("retrofit_route_cache_refresh_period:" + periodTime);
65   }
66
67
68   /*
69    * (non-Javadoc)
70    * 
71    * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method,
72    * java.lang.Object[])
73    */
74   @Override
75   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
76
77     Object retrofitObject = null;
78     ServiceHttpEndPointObjectWapper wapper = null;
79
80     updateMsbInfo();
81     wapper = selectRetrofitObjectByLBStrategy(
82         flowContext.getRetrofitObjectBuilder().buildRetrofitObject(endPointToRetrofitRef, null),
83         method, args);
84     retrofitObject = wapper.retrofitObject;
85
86     Object resultObjecct = method.invoke(retrofitObject, args);
87
88     if (resultObjecct instanceof Call) {
89       Call targetCall = (Call) resultObjecct;
90       return new ProxyRetrofitCall(targetCall, this, wapper.endPoint, proxy, method, args,
91           flowContext.getMetricmanager().getMetricObject(method));
92     }
93     return resultObjecct;
94   }
95
96
97   public Object reInvoke(Object proxy, Method method, Object[] args,
98       ServiceHttpEndPointObject endPoint) throws Throwable {
99
100
101     Object retrofitObject = null;
102     ServiceHttpEndPointObjectWapper wapper = null;
103
104     updateMsbInfo();
105
106     Map<ServiceHttpEndPointObject, Object> serviceHttpEndPointObjectMap =
107         flowContext.getRetrofitObjectBuilder().buildRetrofitObject(endPointToRetrofitRef, endPoint);
108
109     wapper = selectRetrofitObjectByLBStrategy(serviceHttpEndPointObjectMap, method, args);
110
111
112
113     retrofitObject = wapper.retrofitObject;
114
115     Object resultObjecct = method.invoke(retrofitObject, args);
116
117     return resultObjecct;
118
119   }
120
121   private void updateMsbInfo() {
122
123
124
125     if (System.currentTimeMillis() - flowContext.getLastUpdateMsbTime() > periodTime * 1000) {
126       clean();
127     }
128   }
129
130   public void clean() {
131     endPointToRetrofitRef.set(null);
132   }
133
134
135   private ServiceHttpEndPointObjectWapper selectRetrofitObjectByLBStrategy(
136       Map<ServiceHttpEndPointObject, Object> srvEndPointToRetrofit, Method method, Object[] args)
137       throws RetrofitServiceRuntimeException {
138
139     LoadBalanceContext ctx = new LoadBalanceContext();
140     ctx.setEndPoints(Lists.newArrayList(srvEndPointToRetrofit.keySet()));
141     ctx.setArgs(args);
142     ctx.setMethod(method);
143     ServiceHttpEndPointObject endPoint = flowContext.getLbStrategy().chooseEndPointObject(ctx);
144     return new ServiceHttpEndPointObjectWapper(endPoint, srvEndPointToRetrofit.get(endPoint));
145   }
146
147 }
148
149
150 class ServiceHttpEndPointObjectWapper {
151
152   protected ServiceHttpEndPointObject endPoint;
153   protected Object retrofitObject;
154
155   public ServiceHttpEndPointObjectWapper(ServiceHttpEndPointObject endPoint,
156       Object retrofitObject) {
157     super();
158     this.endPoint = endPoint;
159     this.retrofitObject = retrofitObject;
160   }
161
162 }