1: using System;
2: using System.Data;
3: using System.IO;
4: using System.Linq;
5: using System.Text;
6: using System.Text.RegularExpressions;
7:
8: namespace Ia.Ngn.Cl.Model.Ui.Provision
9: {
10: ////////////////////////////////////////////////////////////////////////////
11:
12: /// <summary publish="true">
13: /// Access support class for Optical Fiber Network (OFN) ui model.
14: /// </summary>
15: ///
16: /// <remarks>
17: /// Copyright © 2006-2019 Jasem Y. Al-Shamlan (info@ia.com.kw), Integrated Applications - Kuwait. All Rights Reserved.
18: ///
19: /// This library is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
20: /// the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
21: ///
22: /// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
23: /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
24: ///
25: /// You should have received a copy of the GNU General Public License along with this library. If not, see http://www.gnu.org/licenses.
26: ///
27: /// Copyright notice: This notice may not be removed or altered from any source distribution.
28: /// </remarks>
29: public class Access
30: {
31: /// <summary/>
32: public Access() { }
33:
34: /////////////////////////////////////////////////////////////////////////////////
35:
36: /// <summary>
37: ///
38: /// </summary>
39: public static void Manage(Ia.Ngn.Cl.Model.Business.Administration.StaffContact staffContact, string opcode, string operand, out string responseSubject, out string responseContent)
40: {
41: int i;
42: string line, accessNameRow, odf, kuwaitOfnAreaSymbol, block, street, premisesOld, premisesNew, paci, note;
43: string ontEquipmentTypeString, ontSerialNumber, ip;
44: StringBuilder stringBuilder;
45: DateTime now;
46: Ia.Cl.Model.Result documentValidityResult;
47: Ia.Ngn.Cl.Model.Business.Nokia.Ont.FamilyType ontFamilyType;
48: Ia.Ngn.Cl.Model.Business.Huawei.Ont.EquipmentType emsOntEquipmentType;
49: Ia.Ngn.Cl.Model.Access access;
50: Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Ont nddOnt;
51:
52: documentValidityResult = new Ia.Cl.Model.Result();
53:
54: opcode = opcode.ToLower();
55:
56: now = DateTime.UtcNow.AddHours(3);
57:
58: // subject can't have \r\n
59: responseSubject = "Optical Fiber Network's Operations Support System (OFN OSS) Access Manager (" + now.ToString("yyyy-MM-dd HH:mm") + ")";
60: responseContent = "Optical Fiber Network's Operations Support System (OFN OSS) Access Manager: " + now.ToString("yyyy-MM-dd HH:mm") + "\r\n";
61:
62: if (opcode.Contains("help"))
63: {
64: responseContent += Ia.Ngn.Cl.Model.Data.Help.Text("mail/provision/access");
65: responseContent += "\r\n";
66: }
67: else
68: {
69: if (opcode.StartsWith("mail/provision/access/create"))
70: {
71: if (Ia.Ngn.Cl.Model.Business.Authority.StaffContactCanCreateReadUpdateDeleteAccessList(Ia.Ngn.Cl.Model.Business.Authority.PersistentStorageFunction.Create, staffContact))
72: {
73: responseContent += @"Opcode: """ + opcode + @"""." + "\r\n";
74: //content += @"Operand: """ + operand + @"""." + "\r\n";
75: responseContent += "\r\n";
76:
77: stringBuilder = new StringBuilder(10000);
78:
79: using (StringReader reader = new StringReader(operand))
80: {
81: if (operand.Length > 0)
82: {
83: while ((line = reader.ReadLine()) != null)
84: {
85: if (!string.IsNullOrEmpty(line)) // skip empty lines
86: {
87: if (ParseLine(line, ref stringBuilder, out accessNameRow, out kuwaitOfnAreaSymbol, out block, out street, out premisesOld, out premisesNew, out ontSerialNumber, out ip, out ontEquipmentTypeString, out odf, out paci))
88: {
89: if (ontSerialNumber != "0" && !string.IsNullOrEmpty(ontSerialNumber))
90: {
91: if (Ia.Ngn.Cl.Model.Business.Huawei.Ont.IsValidSerialNumber(ontSerialNumber) || Ia.Ngn.Cl.Model.Business.Nokia.Ont.IsValidSerialNumber(ontSerialNumber)) // to check Huawei and Nokia ONTs
92: {
93: block = Ia.Ngn.Cl.Model.Business.Access.NormalizeBlockEntry(block);
94: street = Ia.Ngn.Cl.Model.Business.Access.NormalizeStreetEntry(street);
95: premisesOld = Ia.Ngn.Cl.Model.Business.Access.NormalizePremisesEntry(premisesOld);
96: premisesNew = Ia.Ngn.Cl.Model.Business.Access.NormalizePremisesEntry(premisesNew);
97: paci = Ia.Ngn.Cl.Model.Business.Access.NormalizePaciEntry(paci);
98: odf = string.Empty; // odfPort;
99:
100: if (!string.IsNullOrEmpty(paci) && int.TryParse(paci, out i))
101: {
102: var accessListByPaci = Ia.Ngn.Cl.Model.Data.Access.ReadListByPaci(paci);
103:
104: // the new access is acceptable if the PACI is new or PACI exists with similar block and premises-old
105: if (accessListByPaci.Count == 0 || accessListByPaci.Any(u => u.Block == block && u.PremisesOld == premisesOld))
106: {
107: if (!string.IsNullOrEmpty(block) /*&& int.TryParse(block, out i)*/) // there are blocks with letters like block 7B
108: {
109: //if (!string.IsNullOrEmpty(street) && int.TryParse(street, out i))
110: //{
111: if (string.IsNullOrEmpty(premisesOld) || int.TryParse(premisesOld, out i))
112: {
113: //if (string.IsNullOrEmpty(premisesNew) || int.TryParse(premisesNew, out i))
114: //{
115: nddOnt = Ia.Ngn.Cl.Model.Business.Default.NddOntUsingExtractedAccessNameWithValidSymbolAndLegalFormatForPonAndOntFromValue(accessNameRow);
116:
117: if (nddOnt != null)
118: {
119: if (nddOnt.Pon.PonGroup.Olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Nokia)
120: {
121: ontFamilyType = Ia.Ngn.Cl.Model.Business.Nokia.Ont.FamilyTypeFromString(ontEquipmentTypeString);
122:
123: if (ontFamilyType != Ia.Ngn.Cl.Model.Business.Nokia.Ont.FamilyType.Undefined)
124: {
125: if (string.IsNullOrEmpty(ip) || ip == nddOnt.Ip)
126: {
127: note = ontEquipmentTypeString + ": " + Ia.Ngn.Cl.Model.Business.Access.NormalizeOntSerialNumberEntry(ontSerialNumber);
128:
129: access = Ia.Ngn.Cl.Model.Business.Access.Create(Ia.Ngn.Cl.Model.Business.Msmq.Application.EmailApplication, nddOnt.Access.Name, kuwaitOfnAreaSymbol, block, street, premisesOld, premisesNew, odf, paci, note, staffContact.UserId, out documentValidityResult);
130:
131: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
132: stringBuilder.AppendLine(documentValidityResult.Message);
133: stringBuilder.AppendLine(" ");
134: }
135: else
136: {
137: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
138: stringBuilder.AppendLine(@"Error: Submitted IP: " + ip + " does not match the Network Design Document (NDD) IP: " + nddOnt.Ip + ". ");
139: stringBuilder.AppendLine(" ");
140: }
141: }
142: else
143: {
144: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
145: stringBuilder.AppendLine(@"Error: ONT family type is undefined. ");
146: stringBuilder.AppendLine(" ");
147: }
148: }
149: else if (nddOnt.Pon.PonGroup.Olt.Odf.Vendor == Ia.Ngn.Cl.Model.Business.NetworkDesignDocument.Vendor.Huawei)
150: {
151: /// This is used to verify the ONT type in the contactors access submittal files
152: emsOntEquipmentType = (from e in Ia.Ngn.Cl.Model.Business.Huawei.Ont.EquipmentTypeList where e.Name == ontEquipmentTypeString select e).SingleOrDefault();
153:
154: if (emsOntEquipmentType != null) // Ia.Ngn.Cl.Model.Business.Huawei.Ont.EquipmentType.Undefined)
155: {
156: note = ontEquipmentTypeString + ": " + Ia.Ngn.Cl.Model.Business.Access.NormalizeOntSerialNumberEntry(ontSerialNumber);
157:
158: access = Ia.Ngn.Cl.Model.Business.Access.Create(Ia.Ngn.Cl.Model.Business.Msmq.Application.EmailApplication, nddOnt.Access.Name, kuwaitOfnAreaSymbol, block, street, premisesOld, premisesNew, odf, paci, note, staffContact.UserId, out documentValidityResult);
159:
160: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
161: stringBuilder.AppendLine(documentValidityResult.Message);
162: stringBuilder.AppendLine(" ");
163: }
164: else
165: {
166: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
167: stringBuilder.AppendLine(@"Error: ONT family type is undefined. ");
168: stringBuilder.AppendLine(" ");
169: }
170: }
171: else
172: {
173: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
174: stringBuilder.AppendLine(@"Error: Access vendor is undefined. ");
175: stringBuilder.AppendLine(" ");
176: }
177: }
178: else
179: {
180: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
181: stringBuilder.AppendLine(@"Error: Network design document does not recognize the access name " + accessNameRow + ". Access vendor is undefined. ");
182: stringBuilder.AppendLine(" ");
183: }
184: }
185: //else
186: //{
187: // stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
188: // stringBuilder.AppendLine(@"Error: PremisesNew number is undefined or invalid. ");
189: // stringBuilder.AppendLine(" ");
190: //}
191: //}
192: else
193: {
194: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
195: stringBuilder.AppendLine(@"Error: PremisesOld (Parcel) number " + premisesOld + " is undefined or invalid. ");
196: stringBuilder.AppendLine(" ");
197: }
198: //}
199: //else
200: //{
201: // stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
202: // stringBuilder.AppendLine(@"Error: Street number is undefined or invalid. ");
203: // stringBuilder.AppendLine(" ");
204: //}
205: }
206: else
207: {
208: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
209: stringBuilder.AppendLine(@"Error: Block number " + block + " is undefined or invalid. ");
210: stringBuilder.AppendLine(" ");
211: }
212: }
213: else
214: {
215: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
216: stringBuilder.AppendLine(@"Error: PACI number " + paci + " is already assigned to another ONT. To submit other ONTs with this same PACI their address must also have the same block and old permises numbers. ");
217: stringBuilder.AppendLine(" ");
218: }
219: }
220: else
221: {
222: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
223: stringBuilder.AppendLine(@"Error: PACI " + paci + " is undefined or invalid. ");
224: stringBuilder.AppendLine(" ");
225: }
226: }
227: else
228: {
229: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
230: stringBuilder.AppendLine(@"Error: ONT serial """ + ontSerialNumber + @""" is not valid. ");
231: stringBuilder.AppendLine(" ");
232: }
233: }
234: else
235: {
236: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
237: stringBuilder.AppendLine(@"Error: ONT serial is null or zero. ");
238: stringBuilder.AppendLine(" ");
239: }
240: }
241: else
242: {
243: // ref stringBuilder has a response
244: //stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
245: //stringBuilder.AppendLine(@"Error: Line format was incorrect and was not matched. ");
246: //stringBuilder.AppendLine(" ");
247: }
248: }
249: }
250: }
251: else
252: {
253: stringBuilder.AppendLine("Error: Operand is empty. ");
254: stringBuilder.AppendLine(" ");
255: }
256: }
257:
258: responseContent += stringBuilder.ToString();
259: responseContent += "\r\n";
260: //content += "\r\nResult: " + result.Message;
261:
262: responseContent += "\r\n";
263: responseContent += "\r\n";
264: responseContent += @"Help? Send email with subject ""mail/provision/access/help"". ";
265: responseContent += "\r\n";
266: responseContent += "\r\n";
267: }
268: else
269: {
270: responseContent += "\r\n";
271: responseContent += "You are not authorized to modify this value. ";
272: responseContent += "\r\n";
273: }
274: }
275: else if (opcode.StartsWith("mail/provision/access/read"))
276: {
277: responseContent += "\r\n";
278: responseContent += "This opcode is not defined yet. ";
279: responseContent += "\r\n";
280: }
281: else if (opcode.StartsWith("mail/provision/access/delete"))
282: {
283: if (Ia.Ngn.Cl.Model.Business.Authority.StaffContactCanCreateReadUpdateDeleteAccessList(Ia.Ngn.Cl.Model.Business.Authority.PersistentStorageFunction.Create, staffContact))
284: {
285: responseContent += @"Opcode: """ + opcode + @"""." + "\r\n";
286: //content += @"Operand: """ + operand + @"""." + "\r\n";
287: responseContent += "\r\n";
288:
289: stringBuilder = new StringBuilder(10000);
290:
291: using (StringReader reader = new StringReader(operand))
292: {
293: if (operand.Length > 0)
294: {
295: while ((line = reader.ReadLine()) != null)
296: {
297: if (!string.IsNullOrEmpty(line)) // skip empty lines
298: {
299: nddOnt = Ia.Ngn.Cl.Model.Business.Default.NddOntUsingExtractedAccessNameWithValidSymbolAndLegalFormatForPonAndOntFromValue(line);
300:
301: if (nddOnt != null)
302: {
303: Ia.Ngn.Cl.Model.Business.Access.Delete(Ia.Ngn.Cl.Model.Business.Msmq.Application.EmailApplication, nddOnt.Access.Name, staffContact.UserId, out documentValidityResult);
304:
305: //Ia.Ngn.Cl.Model.Data.Msmq.AccessNameQueue.ProvisionAccessQueue.Enqueue(nddOnt.Access.Name);
306:
307: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
308: stringBuilder.AppendLine(documentValidityResult.Message);
309: stringBuilder.AppendLine(" ");
310: }
311: else
312: {
313: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
314: stringBuilder.AppendLine(@"Error: Network design document does not recognize the access name " + line + ". Access vendor is undefined. ");
315: stringBuilder.AppendLine(" ");
316: }
317: }
318: }
319: }
320: else
321: {
322: stringBuilder.AppendLine("Error: Operand is empty. ");
323: stringBuilder.AppendLine(" ");
324: }
325: }
326:
327: responseContent += stringBuilder.ToString();
328: responseContent += "\r\n";
329: //content += "\r\nResult: " + result.Message;
330:
331: responseContent += "\r\n";
332: responseContent += "\r\n";
333: responseContent += @"Help? Send email with subject ""mail/provision/access/help"". ";
334: responseContent += "\r\n";
335: responseContent += "\r\n";
336: }
337: else
338: {
339: responseContent += "\r\n";
340: responseContent += "You are not authorized to delete this value. ";
341: responseContent += "\r\n";
342: }
343: }
344: else
345: {
346: responseContent += "\r\n";
347: responseContent += "This opcode is not known. ";
348: responseContent += "\r\n";
349: }
350: }
351: }
352:
353: /////////////////////////////////////////////////////////////////////////////////
354:
355: /// <summary>
356: ///
357: /// </summary>
358: private static bool ParseLine(string line, ref StringBuilder stringBuilder, out string accessName, out string kuwaitOfnAreaSymbol, out string block, out string street, out string premisesOld, out string premisesNew, out string ontSerialNumber, out string ip, out string ontEquipmentTypeString, out string odf, out string paci)
359: {
360: bool matchSuccess;
361: int slNo, pon, pon2, pon3;
362: string accessName2, areaSymbol;
363: Match match;
364:
365: accessName = kuwaitOfnAreaSymbol = block = street = premisesOld = premisesNew = ontSerialNumber = ip = ontEquipmentTypeString = odf = paci = string.Empty;
366:
367: // parse Huawei submittal line
368: match = Regex.Match(line, @"(\d+?)\t(\d+?)\t(\w\w\w)\.(\d+?)\.(\d+?)\t(\w\w\w)\.(\d+?)\.(\d+?)\t(.*?)\t(\w\w\w)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)$");
369: // [5 1126 SMC.1126.002 SMC.1126.002 SHX011 SMC 1 NA 5 PUBLICSERVICCO 18032043 4857544390755A78 10.150.131.34 NA 66081089 MA5616-96]
370: if (match.Success)
371: {
372: slNo = int.Parse(match.Groups[1].Value);
373: pon = int.Parse(match.Groups[2].Value);
374: pon2 = int.Parse(match.Groups[4].Value);
375: pon3 = int.Parse(match.Groups[7].Value);
376:
377: if (pon == pon2 && pon == pon3 && pon2 == pon3)
378: {
379: accessName = match.Groups[3].Value + "." + match.Groups[4].Value + "." + match.Groups[5].Value;
380: accessName2 = match.Groups[6].Value + "." + match.Groups[7].Value + "." + match.Groups[8].Value;
381:
382: kuwaitOfnAreaSymbol = match.Groups[10].Value;
383:
384: if (accessName == accessName2 && accessName.StartsWith(kuwaitOfnAreaSymbol))
385: {
386: //mhNo = match.Groups[9].Value;
387: block = match.Groups[11].Value;
388: premisesNew = match.Groups[12].Value;
389: street = match.Groups[13].Value;
390: premisesOld = match.Groups[14].Value;
391: paci = match.Groups[15].Value;
392: ontSerialNumber = match.Groups[16].Value;
393: ip = match.Groups[17].Value;
394: ontEquipmentTypeString = match.Groups[20].Value;
395: //odfPort = match.Groups[19].Value;
396: //oltPort = match.Groups[20].Value;
397:
398: matchSuccess = true;
399: }
400: else
401: {
402: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
403: stringBuilder.AppendLine(@"Error: TB.ID, ONT ID, and/or area symbol values don't match in line. ");
404: stringBuilder.AppendLine(" ");
405:
406: matchSuccess = false;
407: }
408: }
409: else
410: {
411: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
412: stringBuilder.AppendLine(@"Error: Inconsistent PON (" + pon + "), TB.ID (" + pon2 + ") and ONT ID (" + pon3 + ") values in line. ");
413: stringBuilder.AppendLine(" ");
414:
415: matchSuccess = false;
416: }
417: }
418: else
419: {
420: // parse Nokia submittal line
421: match = Regex.Match(line, @"([a-zA-Z]{3})\.(\d{1,4})\.(\d{1,3})\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.*?)\t(.+?)$");
422:
423: if (match.Success)
424: {
425: areaSymbol = match.Groups[1].Value;
426: kuwaitOfnAreaSymbol = areaSymbol;
427:
428: accessName = areaSymbol + "." + match.Groups[2].Value + "." + match.Groups[3].Value;
429:
430: premisesOld = match.Groups[6].Value;
431: premisesNew = match.Groups[7].Value;
432: street = match.Groups[5].Value;
433: block = match.Groups[4].Value;
434: paci = match.Groups[8].Value;
435:
436: ontSerialNumber = match.Groups[9].Value;
437: ip = string.Empty;
438: ontEquipmentTypeString = match.Groups[10].Value;
439:
440: matchSuccess = true;
441: }
442: else
443: {
444: stringBuilder.AppendLine(@"> [" + line.Trim() + @"]");
445: stringBuilder.AppendLine(@"Error: Line format was incorrect and was not matched. ");
446: stringBuilder.AppendLine(" ");
447:
448: matchSuccess = false;
449: }
450: }
451:
452: return matchSuccess;
453: }
454:
455: ////////////////////////////////////////////////////////////////////////////
456: ////////////////////////////////////////////////////////////////////////////
457: }
458: }