Fixed major Sonar issues in RestMusicBmAPI
[music.git] / src / main / java / org / onap / music / rest / RestMusicBmAPI.java
1 /*
2  * ============LICENSE_START========================================== org.onap.music
3  * =================================================================== Copyright (c) 2017 AT&T
4  * Intellectual Property
5  * Modifications Copyright (C) 2018 IBM.
6  * ===================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  * http://www.apache.org/licenses/LICENSE-2.0
11  * 
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * 
17  * ============LICENSE_END=============================================
18  * ====================================================================
19  */
20 package org.onap.music.rest;
21
22 import java.util.List;
23 import java.util.Map;
24 import java.util.UUID;
25 import javax.ws.rs.Consumes;
26 import javax.ws.rs.GET;
27 import javax.ws.rs.POST;
28 import javax.ws.rs.PUT;
29 import javax.ws.rs.Path;
30 import javax.ws.rs.PathParam;
31 import javax.ws.rs.Produces;
32 import javax.ws.rs.core.Context;
33 import javax.ws.rs.core.MediaType;
34 import javax.ws.rs.core.MultivaluedMap;
35 import javax.ws.rs.core.UriInfo;
36 import org.onap.music.datastore.jsonobjects.JsonInsert;
37 import org.onap.music.eelf.logging.EELFLoggerDelegate;
38 import org.onap.music.main.MusicCore;
39 import org.onap.music.main.MusicUtil;
40 import org.onap.music.main.ResultType;
41 import org.onap.music.main.ReturnType;
42 import org.onap.music.datastore.PreparedQueryObject;
43 import com.datastax.driver.core.DataType;
44 import com.datastax.driver.core.TableMetadata;
45 import io.swagger.annotations.Api;
46
47 /*
48  * These are functions created purely for benchmarking purposes. Commented out Swagger - This should
49  * be undocumented API
50  * 
51  */
52 @Path("/v{version: [0-9]+}/benchmarks/")
53 @Api(value = "Benchmark API", hidden = true)
54 public class RestMusicBmAPI {
55
56     private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMusicBmAPI.class);
57     public static final String UPDATE_CONST=" update-";
58     // pure zk calls...
59
60     /**
61      * 
62      * @param nodeName
63      * @throws Exception
64      */
65     @POST
66     @Path("/purezk/{name}")
67     @Consumes(MediaType.APPLICATION_JSON)
68     public void pureZkCreate(@PathParam("name") String nodeName) throws Exception {
69         MusicCore.pureZkCreate("/" + nodeName);
70     }
71
72
73     /**
74      * 
75      * @param insObj
76      * @param nodeName
77      * @throws Exception
78      */
79     @PUT
80     @Path("/purezk/{name}")
81     @Consumes(MediaType.APPLICATION_JSON)
82     public void pureZkUpdate(JsonInsert insObj, @PathParam("name") String nodeName)
83                     throws Exception {
84         logger.info(EELFLoggerDelegate.applicationLogger,"--------------Zk normal update-------------------------");
85         long start = System.currentTimeMillis();
86         MusicCore.pureZkWrite(nodeName, insObj.serialize());
87         long end = System.currentTimeMillis();
88         logger.info(EELFLoggerDelegate.applicationLogger,"Total time taken for Zk normal update:" + (end - start) + " ms");
89     }
90
91     /**
92      * 
93      * @param nodeName
94      * @return
95      * @throws Exception
96      */
97     @GET
98     @Path("/purezk/{name}")
99     @Consumes(MediaType.TEXT_PLAIN)
100     public byte[] pureZkGet(@PathParam("name") String nodeName) throws Exception {
101         return MusicCore.pureZkRead(nodeName);
102     }
103
104     /**
105      * 
106      * @param insObj
107      * @param lockName
108      * @param nodeName
109      * @throws Exception
110      */
111     @PUT
112     @Path("/purezk/atomic/{lockname}/{name}")
113     @Consumes(MediaType.APPLICATION_JSON)
114     public void pureZkAtomicPut(JsonInsert updateObj, @PathParam("lockname") String lockname,
115                     @PathParam("name") String nodeName) throws Exception {
116         long startTime = System.currentTimeMillis();
117         String operationId = UUID.randomUUID().toString();// just for debugging purposes.
118         String consistency = updateObj.getConsistencyInfo().get("type");
119
120         logger.info(EELFLoggerDelegate.applicationLogger,"--------------Zookeeper " + consistency + UPDATE_CONST + operationId
121                         + "-------------------------");
122
123         byte[] data = updateObj.serialize();
124         long jsonParseCompletionTime = System.currentTimeMillis();
125
126         String lockId = MusicCore.createLockReference(lockname);
127
128         long lockCreationTime = System.currentTimeMillis();
129
130         long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
131         ReturnType lockAcqResult = MusicCore.acquireLockWithLease(lockname, lockId, leasePeriod);
132         long lockAcqTime = System.currentTimeMillis();
133         long zkPutTime = 0;
134         long lockReleaseTime = 0;
135
136         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
137             logger.info(EELFLoggerDelegate.applicationLogger,"acquired lock with id " + lockId);
138             MusicCore.pureZkWrite(lockname, data);
139             zkPutTime = System.currentTimeMillis();
140             boolean voluntaryRelease = true;
141             if (("atomic").equals(consistency))
142                 MusicCore.releaseLock(lockId, voluntaryRelease);
143             else if (("atomic_delete_lock").equals(consistency))
144                 MusicCore.deleteLock(lockname);
145             lockReleaseTime = System.currentTimeMillis();
146         } else {
147             MusicCore.destroyLockRef(lockId);
148         }
149
150         long actualUpdateCompletionTime = System.currentTimeMillis();
151
152
153         long endTime = System.currentTimeMillis();
154
155         String lockingInfo = "|lock creation time:" + (lockCreationTime - jsonParseCompletionTime)
156                         + "|lock accquire time:" + (lockAcqTime - lockCreationTime)
157                         + "|zk put time:" + (zkPutTime - lockAcqTime);
158
159         if ("atomic".equals(consistency))
160             lockingInfo = lockingInfo + "|lock release time:" + (lockReleaseTime - zkPutTime) + "|";
161         else if ("atomic_delete_lock".equals(consistency))
162             lockingInfo = lockingInfo + "|lock delete time:" + (lockReleaseTime - zkPutTime) + "|";
163
164         String timingString = "Time taken in ms for Zookeeper " + consistency + UPDATE_CONST
165                         + operationId + ":" + "|total operation time:" + (endTime - startTime)
166                         + "|json parsing time:" + (jsonParseCompletionTime - startTime)
167                         + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
168                         + lockingInfo;
169
170         logger.info(EELFLoggerDelegate.applicationLogger,timingString);
171     }
172
173     /**
174      * 
175      * @param insObj
176      * @param lockName
177      * @param nodeName
178      * @throws Exception
179      */
180     @GET
181     @Path("/purezk/atomic/{lockname}/{name}")
182     @Consumes(MediaType.APPLICATION_JSON)
183     public void pureZkAtomicGet(JsonInsert insObj, @PathParam("lockname") String lockName,
184                     @PathParam("name") String nodeName) throws Exception {
185         logger.info("--------------Zk atomic read-------------------------");
186         long start = System.currentTimeMillis();
187         String lockId = MusicCore.createLockReference(lockName);
188         long leasePeriod = MusicUtil.getDefaultLockLeasePeriod();
189         ReturnType lockAcqResult = MusicCore.acquireLockWithLease(lockName, lockId, leasePeriod);
190         if (lockAcqResult.getResult().equals(ResultType.SUCCESS)) {
191             logger.info("acquired lock with id " + lockId);
192             MusicCore.pureZkRead(nodeName);
193             boolean voluntaryRelease = true;
194             MusicCore.releaseLock(lockId, voluntaryRelease);
195         } else {
196             MusicCore.destroyLockRef(lockId);
197         }
198
199         long end = System.currentTimeMillis();
200         logger.info(EELFLoggerDelegate.applicationLogger,"Total time taken for Zk atomic read:" + (end - start) + " ms");
201     }
202
203     /**
204      *
205      * doing an update directly to cassa but through the rest api
206      * 
207      * @param insObj
208      * @param keyspace
209      * @param tablename
210      * @param info
211      * @return
212      * @throws Exception
213      */
214     @PUT
215     @Path("/cassa/keyspaces/{keyspace}/tables/{tablename}/rows")
216     @Consumes(MediaType.APPLICATION_JSON)
217     @Produces(MediaType.APPLICATION_JSON)
218     public boolean updateTableCassa(JsonInsert insObj, @PathParam("keyspace") String keyspace,
219                     @PathParam("tablename") String tablename, @Context UriInfo info)
220                     throws Exception {
221         long startTime = System.currentTimeMillis();
222         String operationId = UUID.randomUUID().toString();// just for debugging purposes.
223         String consistency = insObj.getConsistencyInfo().get("type");
224         logger.info(EELFLoggerDelegate.applicationLogger,"--------------Cassandra " + consistency + UPDATE_CONST + operationId
225                         + "-------------------------");
226         PreparedQueryObject queryObject = new PreparedQueryObject();
227         Map<String, Object> valuesMap = insObj.getValues();
228         TableMetadata tableInfo = MusicCore.returnColumnMetadata(keyspace, tablename);
229         String vectorTs = "'" + Thread.currentThread().getId() + System.currentTimeMillis() + "'";
230         String fieldValueString = "vector_ts= ? ,";
231         queryObject.addValue(vectorTs);
232
233         int counter = 0;
234         for (Map.Entry<String, Object> entry : valuesMap.entrySet()) {
235             Object valueObj = entry.getValue();
236             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
237             Object valueString = MusicUtil.convertToActualDataType(colType, valueObj);
238             fieldValueString = fieldValueString + entry.getKey() + "= ?";
239             queryObject.addValue(valueString);
240             if (counter != valuesMap.size() - 1)
241                 fieldValueString = fieldValueString + ",";
242             counter = counter + 1;
243         }
244
245         // get the row specifier
246         String rowSpec = "";
247         counter = 0;
248         queryObject.appendQueryString("UPDATE " + keyspace + "." + tablename + " ");
249         MultivaluedMap<String, String> rowParams = info.getQueryParameters();
250         String primaryKey = "";
251         for (MultivaluedMap.Entry<String, List<String>> entry : rowParams.entrySet()) {
252             String keyName = entry.getKey();
253             List<String> valueList = entry.getValue();
254             String indValue = valueList.get(0);
255             DataType colType = tableInfo.getColumn(entry.getKey()).getType();
256             Object formattedValue = MusicUtil.convertToActualDataType(colType, indValue);
257             primaryKey = primaryKey + indValue;
258             rowSpec = rowSpec + keyName + "= ? ";
259             queryObject.addValue(formattedValue);
260             if (counter != rowParams.size() - 1)
261                 rowSpec = rowSpec + " AND ";
262             counter = counter + 1;
263         }
264
265
266         String ttl = insObj.getTtl();
267         String timestamp = insObj.getTimestamp();
268
269         if ((ttl != null) && (timestamp != null)) {
270
271             logger.info(EELFLoggerDelegate.applicationLogger,"both there");
272             queryObject.appendQueryString(" USING TTL ? AND TIMESTAMP ?");
273             queryObject.addValue(Integer.parseInt(ttl));
274             queryObject.addValue(Long.parseLong(timestamp));
275         }
276
277         if ((ttl != null) && (timestamp == null)) {
278             logger.info(EELFLoggerDelegate.applicationLogger,"ONLY TTL there");
279             queryObject.appendQueryString(" USING TTL ?");
280             queryObject.addValue(Integer.parseInt(ttl));
281         }
282
283         if ((ttl == null) && (timestamp != null)) {
284             logger.info(EELFLoggerDelegate.applicationLogger,"ONLY timestamp there");
285             queryObject.appendQueryString(" USING TIMESTAMP ?");
286             queryObject.addValue(Long.parseLong(timestamp));
287         }
288         queryObject.appendQueryString(" SET " + fieldValueString + " WHERE " + rowSpec + ";");
289
290         long jsonParseCompletionTime = System.currentTimeMillis();
291
292         boolean operationResult = true;
293         MusicCore.getDSHandle().executePut(queryObject, insObj.getConsistencyInfo().get("type"));
294
295         long actualUpdateCompletionTime = System.currentTimeMillis();
296
297         long endTime = System.currentTimeMillis();
298
299         String timingString = "Time taken in ms for Cassandra " + consistency + UPDATE_CONST
300                         + operationId + ":" + "|total operation time:" + (endTime - startTime)
301                         + "|json parsing time:" + (jsonParseCompletionTime - startTime)
302                         + "|update time:" + (actualUpdateCompletionTime - jsonParseCompletionTime)
303                         + "|";
304         logger.info(EELFLoggerDelegate.applicationLogger,timingString);
305
306         return operationResult;
307     }
308 }