104ad0364e4b0272da52c75eebd86b47e1e38440
[ccsdk/features.git] /
1 /*
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt
4  * =================================================================================================
5  * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
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  * ============LICENSE_END==========================================================================
17  */
18 package org.onap.ccsdk.features.sdnr.wt.devicemanager.test.util;
19
20 import java.text.ParseException;
21 import java.text.SimpleDateFormat;
22 import java.util.Date;
23 import java.util.TimeZone;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * Function is handling the NETCONF and the format used by database and restconf communication.
32  *
33  * Input supported for the formats used in NETCONF messages:
34  *
35  * Format1 ISO 8601 2017-01-18T11:44:49.482-05:00
36  *
37  * Format2 NETCONF - pattern from ietf-yang-types "2013-07-15" Pattern:
38  * "\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[\+\-](\d{2}):(\d{2}))"
39  *
40  * Format3 NETCONF DateAndTime CoreModel-CoreFoundationModule-TypeDefinitions vom 2016-07-01 Example1: 20170118114449.1Z
41  * Example2: 20170118114449.1-0500 Pattern: "\d{4}\d{2}\d{2}\d{2}\d{2}\d{2}.\d+?(Z|[\+\-](\d{2})(\d{2}))" typedef
42  * DateAndTime { description "This primitive type defines the date and time according to the following structure:
43  * 'yyyyMMddhhmmss.s[Z|{+|-}HHMm]' where: yyyy '0000'..'9999' year MM '01'..'12' month dd '01'..'31' day hh '00'..'23'
44  * hour mm '00'..'59' minute ss '00'..'59' second s '.0'..'.9' tenth of second (set to '.0' if EMS or NE cannot support
45  * this granularity) Z 'Z' indicates UTC (rather than local time) {+|-} '+' or '-' delta from UTC HH '00'..'23' time
46  * zone difference in hours Mm '00'..'59' time zone difference in minutes."; type string; } Format4 E/// specific
47  * Example1: 2017-01-23T13:32:38-05:00 Example2: 2017-01-23T13:32-05:00
48  *
49  * Input formats netconfTime as String according the formats given above
50  *
51  * Return format is String in ISO8601 Format for database and presentation.
52  *
53  * Example formats: 1) ISO8601. Example 2017-01-18T11:44:49.482-05:00 2) Microwave ONF. Examples 20170118114449.1Z,
54  * 20170118114449.1-0500 3.1) Ericson. Example: 2017-01-23T13:32:38-05:00 3.2) Ericson. Example: 2017-01-23T13:32-05:00
55  * Always 10 Groups, 1:Year 2:Month 3:day 4:Hour 5:minute 6:optional sec 7:optional ms 8:optional Z or 9:offset
56  * signedhour 10:min
57  *
58  * Template: private static final NetconfTimeStamp NETCONFTIME_CONVERTER = NetconfTimeStamp.getConverter();
59  */
60
61 public class NetconfTimeStampOld {
62     private static final Logger LOG = LoggerFactory.getLogger(NetconfTimeStampOld.class);
63
64     private static final NetconfTimeStampOld CONVERTER = new NetconfTimeStampOld();
65
66     private final SimpleDateFormat dateFormatResult = init("yyyy-MM-dd'T'HH:mm:ss.S'Z'", TimeZone.getTimeZone("GMT"));
67     private final SimpleDateFormat dateFormatConvert = init("yyyy-MM-dd HH:mm:ss.S", TimeZone.getTimeZone("GMT"));
68     private static int MILLISECONDSDIGITS = 3; // Digits of milliseconds in dateFormatResult
69     private static String MILLISECONDZEROS = "000"; // String with zeros for milliseconds in dateFormatResult
70     private static final Pattern dateNetconfPatter = Pattern.compile(
71             "(\\d{4})-?(\\d{2})-?(\\d{2})T?(\\d{2}):?(\\d{2})(?:(?::?)(\\d{2}))?(?:.(\\d+))?(?:(Z)|([+-]\\d{2}):?(\\d{2}))");
72
73     /*
74      * ------------------------------------ Public function
75      */
76
77     /**
78      * Use static access
79      */
80     private NetconfTimeStampOld() {}
81
82     /**
83      * Use this function to get the converter
84      * 
85      * @return global converter
86      */
87     public static NetconfTimeStampOld getConverter() {
88         return CONVERTER;
89     }
90
91     /**
92      * Get actual timestamp as NETCONF specific type NETCONF/YANG 1.0 Format
93      *
94      * @return String with Date in NETCONF/YANG Format Version 1.0.
95      */
96     public String getTimeStampAsNetconfString() {
97         return this.getRightFormattedDate(new Date().getTime());
98     }
99
100     /**
101      * Get actual timestamp as NETCONF specific type NETCONF/YANG 1.0 Format
102      * 
103      * @return String with Date in NETCONF/YANG Format Version 1.0.
104      */
105     public String getTimeStampAsNetconfString(Date date) {
106         return getRightFormattedDate(date.getTime());
107     }
108
109     /**
110      * Get actual timestamp as NETCONF specific type NETCONF/YANG 1.0 Format in GMT
111      *
112      * @return DateAndTime Type 1.0. Date in NETCONF/YANG Format Version 1.0.
113      */
114     public DateAndTime getTimeStamp() {
115         return DateAndTime.getDefaultInstance(getTimeStampAsNetconfString());
116     }
117
118     /**
119      * Get time from date as NETCONF specific type NETCONF/YANG 1.0 Format in GMT
120      * 
121      * @param date specifying the date and time
122      * @return DateAndTime Type 1.0. Date in NETCONF/YANG Format Version 1.0.
123      */
124     public DateAndTime getTimeStamp(Date date) {
125         return DateAndTime.getDefaultInstance(getTimeStampAsNetconfString(date));
126     }
127
128
129     /**
130      * Return the String with a NETCONF time converted to long
131      *
132      * @param netconfTime as String according the formats given above
133      * @return Epoch milliseconds
134      * @throws IllegalArgumentException In case of no compliant time format definition for the string
135      * @throws ParseException Time parsing failed
136      */
137     public long getTimeStampFromNetconfAsMilliseconds(String netconfTime) throws IllegalArgumentException {
138         Matcher m = dateNetconfPatter.matcher(netconfTime);
139         // According to specified matches there have to be 10 parameter
140         if (m.matches() && m.groupCount() == 10) {
141             // Convert now
142             synchronized (dateFormatConvert) {
143                 long utcMillis;
144                 try {
145                     utcMillis = dateFormatConvert.parse(getTimeAsNormalizedString(m, m.group(6), m.group(7))).getTime()
146                             - getTimezoneOffsetMilliseconds(m.group(9), m.group(10));
147                     return utcMillis;
148                 } catch (ParseException e) {
149                     throw new IllegalArgumentException("Parse problem for NETCONF data string: " + netconfTime);
150                 }
151             }
152         } else {
153             throw new IllegalArgumentException("No pattern for NETCONF data string: " + netconfTime);
154         }
155     }
156
157     /**
158      * Deliver String result.
159      *
160      * @param netconfTime as String according the formats given above
161      * @return If successful: String in ISO8601 Format for database and presentation. If "wrong formed input" the Input
162      *         string with the prefix "Mailformed date" is delivered back.
163      */
164     public String getTimeStampFromNetconf(String netconfTime) {
165         Matcher m = dateNetconfPatter.matcher(netconfTime);
166         // According to spezified matches there have to be 10 parameter
167         if (m.matches() && m.groupCount() == 10) {
168             // Convert now
169             try {
170                 synchronized (dateFormatConvert) {
171                     long utcMillis =
172                             dateFormatConvert.parse(getTimeAsNormalizedString(m, m.group(6), m.group(7))).getTime()
173                                     - getTimezoneOffsetMilliseconds(m.group(9), m.group(10));
174                     return getRightFormattedDate(utcMillis);
175                 }
176             } catch (ParseException e) {
177                 LOG.info(e.getMessage());
178             } catch (IllegalArgumentException e) {
179                 LOG.info(e.getMessage());
180             }
181         }
182         LOG.debug("No pattern for NETCONF data string: {}", netconfTime);
183         return "Malformed date: " + netconfTime; // Error handling
184     }
185
186     /*-------------------------------------------
187      * Private and static functions
188      */
189     /**
190      * Convert timeZone parameter in format [+-]/d/d:/d/d into milliseconds
191      *
192      * @param m Index 9 with "+/-" and hour string or null for UTZ, Index 10 with minutes
193      * @return long milliseconds of TimeZoneOffset
194      * @throws IllegalArgumentException If parameters are wrong
195      */
196     private static long getTimezoneOffsetMilliseconds(String timeZoneHour, String timeZoneMinute)
197             throws IllegalArgumentException {
198         // -- Calculate timezone specific offset
199         long timeZoneOffsetMilliseconds = 0;
200         if (timeZoneHour != null) {
201             // Time zone offset in hours and minutes
202             int tzHour = 0;
203             int tzMinutes = 0;
204             tzHour = Integer.valueOf(timeZoneHour);
205             if (timeZoneMinute != null) {
206                 tzMinutes = Integer.valueOf(timeZoneMinute);
207             } else {
208                 throw new IllegalArgumentException("Problem in Netconf Time format timeZone minutes parameter.");
209             }
210             timeZoneOffsetMilliseconds = (tzHour * 60 + (tzHour > 0 ? tzMinutes : -tzMinutes)) * 60000L;
211         }
212         return timeZoneOffsetMilliseconds;
213     }
214
215     /**
216      * Convert parameters to String with year .. minutes and optional Seconds and .. milliseconds
217      *
218      * @param m Matcher with parsed date
219      * @param secString Seconds as String or null
220      * @param msString Milliseconds as String or null
221      * @return Normalized time string
222      */
223     private static String getTimeAsNormalizedString(Matcher m, String secString, String msString) {
224         // -- Create time as normalized string
225         StringBuffer sb = new StringBuffer();
226         sb.append(m.group(1)); // year
227         sb.append('-');
228         sb.append(m.group(2)); // Month
229         sb.append('-');
230         sb.append(m.group(3)); // Day
231         sb.append(' ');
232         sb.append(m.group(4)); // Hour 0-23
233         sb.append(':');
234         sb.append(m.group(5)); // Minute
235         sb.append(':');
236         sb.append(secString != null ? secString : "00"); // Seconds (optional)
237         sb.append('.');
238         if (msString == null) { // Milliseconds optional
239             sb.append(MILLISECONDZEROS);
240         } else if (msString.length() <= MILLISECONDSDIGITS) {
241             sb.append(msString); // Millisecond
242             sb.append(MILLISECONDZEROS.substring(0, MILLISECONDSDIGITS - msString.length()));
243         } else {
244             sb.append(msString.substring(0, MILLISECONDSDIGITS)); // Only first Three
245         }
246         return sb.toString();
247     }
248
249     /**
250      * Deliver format in a way that milliseconds are correct.
251      *
252      * @param dateMillis Date as milliseconds in Java definition
253      * @return String
254      */
255     private String getRightFormattedDate(long dateMillis) {
256         long tenthOfSeconds = dateMillis % 1000 / 100L; // Extract 100 milliseconds
257         long base = dateMillis / 1000L * 1000L; // Cut milliseconds to 000
258         Date newDate = new Date(base + tenthOfSeconds);
259         synchronized (dateFormatResult) {
260             return dateFormatResult.format(newDate);
261         }
262     }
263
264     /**
265      * Static initialization
266      */
267     private static SimpleDateFormat init(String format, TimeZone zone) {
268         if (zone == null) {
269             throw new ExceptionInInitializerError();
270         } else {
271             SimpleDateFormat dateFormat;
272             dateFormat = new SimpleDateFormat(format);
273             dateFormat.setTimeZone(zone);
274             return dateFormat;
275         }
276     }
277
278
279
280 }