Taking in latest xapp-frame for alarm-go
[ric-plt/alarm-go.git] / manager / cmd / utils.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    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
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package main
21
22 import (
23         "archive/zip"
24         "encoding/json"
25         "io"
26         "io/ioutil"
27         "net/http"
28         "os"
29         "path/filepath"
30         "strings"
31
32         app "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
33 )
34
35 type Utils struct {
36         baseDir string
37         status  string
38 }
39
40 func NewUtils() *Utils {
41         b := app.Config.GetString("controls.symptomdata.baseDir")
42         if b == "" {
43                 b = "/tmp/symptomdata/"
44         }
45
46         return &Utils{
47                 baseDir: b,
48         }
49 }
50
51 func (u *Utils) FileExists(f string) bool {
52         _, err := os.Stat(f)
53         return err == nil || os.IsExist(err)
54 }
55
56 func (u *Utils) CreateDir(path string) error {
57         if u.FileExists(path) {
58                 os.RemoveAll(path)
59         }
60         err := os.MkdirAll(path, os.ModePerm)
61         if err != nil {
62                 return err
63         }
64         os.Chmod(path, os.ModePerm)
65         return nil
66 }
67
68 func (u *Utils) DeleteFile(fileName string) {
69         os.Remove(fileName)
70 }
71
72 func (u *Utils) AddFileToZip(zipWriter *zip.Writer, filePath string, filename string) error {
73         fileToZip, err := os.Open(filename)
74         if err != nil {
75                 return err
76         }
77         defer fileToZip.Close()
78
79         info, err := fileToZip.Stat()
80         if err != nil {
81                 return err
82         }
83
84         header, err := zip.FileInfoHeader(info)
85         if err != nil {
86                 return err
87         }
88
89         if strings.HasPrefix(filename, filePath) {
90                 filename = strings.TrimPrefix(filename, filePath)
91         }
92         header.Name = filename
93         header.Method = zip.Deflate
94
95         writer, err := zipWriter.CreateHeader(header)
96         if err != nil {
97                 return err
98         }
99         if info.Size() > 0 {
100                 _, err = io.Copy(writer, fileToZip)
101         }
102         return err
103 }
104
105 func (u *Utils) ZipFiles(newZipFile *os.File, filePath string, files []string) error {
106         defer newZipFile.Close()
107         zipWriter := zip.NewWriter(newZipFile)
108         defer zipWriter.Close()
109         for _, file := range files {
110                 if err := u.AddFileToZip(zipWriter, filePath, file); err != nil {
111                         app.Logger.Error("AddFileToZip() failed: %+v", err.Error())
112                         return err
113                 }
114         }
115
116         return nil
117 }
118
119 func (u *Utils) FetchFiles(filePath string, fileList []string) []string {
120         files, err := ioutil.ReadDir(filePath)
121         if err != nil {
122                 app.Logger.Error("ioutil.ReadDir failed: %+v", err)
123                 return nil
124         }
125         for _, file := range files {
126                 if !file.IsDir() {
127                         fileList = append(fileList, filepath.Join(filePath, file.Name()))
128                 } else {
129                         subPath := filepath.Join(filePath, file.Name())
130                         subFiles, _ := ioutil.ReadDir(subPath)
131                         for _, subFile := range subFiles {
132                                 if !subFile.IsDir() {
133                                         fileList = append(fileList, filepath.Join(subPath, subFile.Name()))
134                                 } else {
135                                         fileList = u.FetchFiles(filepath.Join(subPath, subFile.Name()), fileList)
136                                 }
137                         }
138                 }
139         }
140         return fileList
141 }
142
143 func (u *Utils) WriteToFile(fileName string, data string) error {
144         f, err := os.Create(fileName)
145         defer f.Close()
146
147         if err != nil {
148                 app.Logger.Error("Unable to create file %s': %+v", fileName, err)
149         } else {
150                 _, err := io.WriteString(f, data)
151                 if err != nil {
152                         app.Logger.Error("Unable to write to file '%s': %+v", fileName, err)
153                         u.DeleteFile(fileName)
154                 }
155         }
156         return err
157 }
158
159 func (u *Utils) SendSymptomDataJson(w http.ResponseWriter, req *http.Request, data interface{}, n string) {
160         w.Header().Set("Content-Type", "application/json")
161         w.Header().Set("Content-Disposition", "attachment; filename="+n)
162         w.WriteHeader(http.StatusOK)
163         if data != nil {
164                 response, _ := json.Marshal(data)
165                 w.Write(response)
166         }
167 }
168
169 func (u *Utils) SendSymptomDataFile(w http.ResponseWriter, req *http.Request, baseDir, zipFile string) {
170         // Compress and reply with attachment
171         tmpFile, err := ioutil.TempFile("", "symptom")
172         if err != nil {
173                 u.SendSymptomDataError(w, req, "Failed to create a tmp file: "+err.Error())
174                 return
175         }
176         defer os.Remove(tmpFile.Name())
177
178         var fileList []string
179         fileList = u.FetchFiles(baseDir, fileList)
180         err = u.ZipFiles(tmpFile, baseDir, fileList)
181         if err != nil {
182                 u.SendSymptomDataError(w, req, "Failed to zip the files: "+err.Error())
183                 return
184         }
185
186         w.Header().Set("Content-Disposition", "attachment; filename="+zipFile)
187         http.ServeFile(w, req, tmpFile.Name())
188 }
189
190 func (u *Utils) SendSymptomDataError(w http.ResponseWriter, req *http.Request, message string) {
191         w.Header().Set("Content-Disposition", "attachment; filename=error_status.txt")
192         http.Error(w, message, http.StatusInternalServerError)
193 }