2024. 1. 1. 15:29ㆍ개발/C#
2023.12.24 - [개발/C#] - 모니터링 자동화 - 비동기 변경
지금까지 자동화를 한다고 개발을 했지만
생각해보면 자동화 라는 단어가 어울리지 않는다
프로그램 실행 후, 파일을 선택한 뒤
사용자가 직접 로그인(부정방지 문자, 구글 OTP)을 해야하는
단점을 고치고싶었다.
API 호출 및 Parsing
사내 다른 파트에 요청해서
API를 전달받았다.
2가지의 API가 있는데
1. 전체 수용가 목록 List ( 호출 1회 )
2. 수용가 1개의 세부정보 List ( 호출 n회 - API 1에서 받아온 수용가 수 만큼 )
각 데이터를 Parsing해서
로그인 과정을 없앨 예정이다
로그인 후, 웹 크롤링 방식에서
웹의 데이터를 받아오는 API를 호출하는 방식으로 변경
public void SaveCompanyIdAndName()
{
HttpWebRequest request = WebRequest.Create(API_Company_Info) as HttpWebRequest;
request.Method = "GET";
WebResponse webResp = request.GetResponse();
Stream responseStream = webResp.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string result = reader.ReadToEnd();
JObject json = JObject.Parse(result);
JArray dataArray = (JArray)json["data"];
for (int i = 0; i < dataArray.Count; i++)
{
JObject data = (JObject)dataArray[i];
string code = data["structure_1"].ToString();
string name = data["structure_2"].ToString();
string id = data["structure_3"].ToString();
CompanyInfo company = new CompanyInfo
{
Code = code,
Name = name,
Id = id
};
companyMgr.CompanyList.Add(company);
}
}
첫번째 API 호출 및 파싱
보안상 API 데이터 값을 보여줄 순 없고
structure_1 , 2, 3 으로 표현했다.
각각의 값을 Parsing 해서, 전체 수용가 정보를
CompanyInfo class 로 선언해서 저장한다.
생성된 각각의 CompanyInfo class(수용가 1개의 정보)는
CompanyList 리스트에 저장된다.
즉, 수용가 A B C가 있으면
A 클래스 B 클래스 C 클래스 생성 후,
3개의 클래스를 List에 저장한다.
public void SaveCompanyStatus()
{
int percentage = 0;
for (int i = 0; i < companyMgr.CompanyList.Count; i++)
{
string url = API_Company_Channel + companyMgr.CompanyList[i].Code;
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
WebResponse webResp = request.GetResponse();
Stream responseStream = webResp.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string result = reader.ReadToEnd();
JObject json = JObject.Parse(result);
JObject companyInfo = (JObject)json["data"]["data_detail"];
if (companyInfo != null) // 수용가 평균 수신율, 전체장비 수, 연결장비 수 저장
{
int dc = (int)companyInfo ["dc"];
double fr = (double)companyInfo["fr"];
int dcc = (int)companyInfo ["dcc"];
companyMgr.CompanyList[i].DeviceCount = dc;
companyMgr.CompanyList[i].FactoryReceiveRate = fr;
companyMgr.CompanyList[i].DeviceConnectedCount = dcc;
}
JArray companyChannelInfo = (JArray)json["data"]["dcsl"];
if (companyChannelInfo != null) // 수용가 1개의, 이슈발생 채널 목록 저장
{
for(int j=0; j < companyChannelInfo.Count; j++)
{
JObject channel = (JObject)companyChannelInfo[j];
string status = (string)channel["err"];
if (status == "Y")
{
string ip = (string)channel["ip"];
string cs = (string)channel["cS"];
double rr = Math.Round((double)channel["rR"],1); // 소수점 첫째자리 까지만 표시
CompanyChannelInfo companyChannel = new CompanyChannelInfo
{
ChannelIp = ip,
ConnectionStatus = cs,
ReceiveRatio = rr
};
companyMgr.CompanyList[i].Channels.Add(companyChannel);
}
}
}
companyMgr.CompanyList[i].DeleteOverlap();
percentage = (int)((double)33 / companyMgr.CompanyList.Count * (i + 1));
backgroundWorker.ReportProgress(percentage);
}
}
두번째 API 파싱 작업도
보안상 API데이터 구조를 변경해서 포스팅한다.
각 수용가마다 이슈사항을 파악하고
이슈 발생 장비의 정보들을 class로 저장한다.
Class 구조
public class CompanyInfo
{
#region 수용가 전체정보 API property
public string Code { get; set; }
public string Name { get; set; }
public string Id { get; set; }
public int DC { get; set; }
public double FRR { get; set; }
public int DCC { get; set; }
public List<CompanyChannelInfo> Channels { get; set; }
#endregion
public CompanyInfo()
{
Channels = new List<CompanyChannelInfo>();
}
public class CompanyChannelInfo
{
public string IS { get; set; }
public int CN { get; set; }
public string CI { get; set; }
public string CNE { get; set; }
public string CS { get; set; }
public double RR { get; set; }
public int DI { get; set; }
}
}
CompanyInfo 클래스에
1개 수용가의 정보가 저장된다
Code, Name, Id 등의 정보를
get set으로 처리했다.
public List<CompanyChannelInfo> Channels { get; set; }
해당 List는, 수용가 1개 기준
이슈사항이 있는 장비 목록을 저장한다.
CompanyChannelInfo 클래스 형식으로 저장된다.
public class CompanyChannelInfo
{
public string IS { get; set; }
public int CN { get; set; }
public string CI { get; set; }
public string CNE { get; set; }
public string CS { get; set; }
public double RR { get; set; }
public int DI { get; set; }
}
CompanyChannelInfo 클래스는
장비 1개의 정보다.
A 수용가에, 장비가 100개 있으면
1. CompanyInfo 클래스 new 생성
2. 해당 클래스 안의 Channels List에
100개의 장비 중, 이슈 장비만 저장
(이슈 상태는 API 호출 시 확인가능)
위와 같이 저장된다.
원래는 class 구조를 잡지 않고
API 호출해서, 변수에 데이터만 저장했는데
수용가 별 API를 호출하는 도중에
오류 발생해 API 호출 실패 시,
데이터 관리가 힘들어
따로 구조를 잡아서 API 데이터를 저장하기로 했다.
'개발 > C#' 카테고리의 다른 글
C# - class & structure (1) | 2024.02.10 |
---|---|
소프트웨어 설계 수정 (0) | 2024.01.08 |
C# 반복문 변수 선언과 메모리에 관한 고찰 (0) | 2023.12.28 |
모니터링 자동화 - 비동기 변경 (0) | 2023.12.24 |
모니터링 자동화 - Excel Write (2) | 2023.12.21 |