Persoenliche Mediazentrale
ulrich
2021-05-06 f70acbb491c6421623cca57292a75f1820efad4d
commit | author | age
b379f5 1 /*
94b1c2 2   Tango - Personal Media Center
5f70da 3   Copyright (C) 2021  Ulrich Hilger
U 4
5   This program is free software: you can redistribute it and/or modify
6   it under the terms of the GNU Affero General Public License as
7   published by the Free Software Foundation, either version 3 of the
8   License, or (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU Affero General Public License for more details.
14
15   You should have received a copy of the GNU Affero General Public License
16   along with this program.  If not, see <https://www.gnu.org/licenses/>.
b379f5 17  */
94b1c2 18 package de.uhilger.tango.api;
b379f5 19
U 20 import com.google.gson.Gson;
f70acb 21 import com.sun.net.httpserver.HttpContext;
b379f5 22 import com.sun.net.httpserver.HttpExchange;
94b1c2 23 import de.uhilger.tango.App;
U 24 import static de.uhilger.tango.App.RB_EP_LISTE;
25 import static de.uhilger.tango.App.RB_EP_LISTE_ALLES;
26 import de.uhilger.tango.Server;
27 import de.uhilger.tango.entity.Ablageort;
28 import de.uhilger.tango.store.FileStorage;
29 import de.uhilger.tango.entity.Entity;
30 import de.uhilger.tango.entity.Geraet;
31 import static de.uhilger.tango.store.FileStorage.ST_ABLAGEORT;
32 import static de.uhilger.tango.store.FileStorage.ST_GERAET;
33 import de.uhilger.tango.store.Storage;
f70acb 34 import java.io.File;
b379f5 35 import java.io.IOException;
d769f3 36 import java.net.URI;
U 37 import java.util.Iterator;
2b5c60 38 import java.util.List;
081606 39 import java.util.logging.Level;
b379f5 40 import java.util.logging.Logger;
d769f3 41
U 42 import java.net.http.HttpClient;
43 import java.net.http.HttpClient.Version;
44 import java.net.http.HttpClient.Redirect;
45 import java.net.http.HttpRequest;
46 import java.net.http.HttpResponse;
47 import java.net.http.HttpResponse.BodyHandlers;
48 import java.time.Duration;
49 import java.util.ArrayList;
50
b379f5 51
U 52 /**
2597cd 53  * HttpHandler fuer die Verwaltung von Entitaeten der Mediazentrale
a29f5c 54  * 
fe0cf7 55  * GET /mz/api/store/[typname]/[name]
U 56  * GET /mz/api/store/[typname]/liste
57  * GET /mz/api/store/[typname]/listealles  (nur Typ Geraet)
5f70da 58  * 
U 59  * @author Ulrich Hilger
60  * @version 1, 5.4.2021
b379f5 61  */
8d7d35 62 public class StorageHandler extends AbstractHandler {
b379f5 63   
081606 64   private static final Logger logger = Logger.getLogger(StorageHandler.class.getName());
f70acb 65   
U 66   private String conf;
67   
68   public StorageHandler(String conf) {
69     this.conf = conf;
70   }
b379f5 71
8d7d35 72   @Override
U 73   protected String put(HttpExchange e) throws IOException {
dfb7d3 74     String path = e.getRequestURI().toString();
0e9cd3 75     String[] elems = path.split(Server.SLASH);
dfb7d3 76     String type = elems[elems.length - 2];
U 77     String elemName = elems[elems.length - 1]; // alter Name, wenn Aenderung
f70acb 78     if(!elemName.equalsIgnoreCase(getResString(RB_EP_LISTE))) {
U 79       FileStorage fs = new FileStorage(conf);
dfb7d3 80       Gson gson = new Gson();
U 81       logger.log(Level.FINE, "type: {0}, token: {1}", new Object[]{type, fs.typeFromName(type).getType().getTypeName()});
82       Object o = gson.fromJson(bodyLesen(e), fs.typeFromName(type).getType());
83       if(o instanceof Entity) {
84         Entity entity = (Entity) o;
0c14c0 85         if(fs.exists(type, elemName)) { // Aenderung
dfb7d3 86           fs.delete(type, elemName);
0c14c0 87           // wenn Ablageort, hier noch alten Kontext entfernen
U 88           if(type.equalsIgnoreCase(FileStorage.ST_ABLAGEORT)) {
89             Entity aoe = fs.read(type, elemName);
90             if(aoe instanceof Ablageort) {
91               Ablageort ablageort = (Ablageort) aoe;
f70acb 92               //App.getServer().ablageortEntfernen(ablageort.getUrl());      
U 93               e.getHttpContext().getServer().removeContext(ablageort.getUrl());
0c14c0 94             }
U 95           }
dfb7d3 96           fs.write(entity, true);
0c14c0 97           // wenn Ablageort, hier noch neuen Kontext anlegen
U 98           if(type.equalsIgnoreCase(FileStorage.ST_ABLAGEORT)) {
99             if(entity instanceof Ablageort) {
100               Ablageort ablageort = (Ablageort) entity;
f70acb 101               //App.getServer().ablageortHinzufuegen(ablageort);
U 102               ablageortHinzufuegen(e, ablageort);
0c14c0 103             }
U 104           }
105         } else { // Neu
dfb7d3 106           fs.write(entity, false);
0c14c0 107           // wenn Ablageort, hier noch neuen Kontext anlegen
U 108           if(type.equalsIgnoreCase(FileStorage.ST_ABLAGEORT)) {
109             if(entity instanceof Ablageort) {
110               Ablageort ablageort = (Ablageort) entity;
f70acb 111               //App.getServer().ablageortHinzufuegen(ablageort);
U 112               ablageortHinzufuegen(e, ablageort);
0c14c0 113             }
U 114           }
dfb7d3 115         }
0e9cd3 116         return type + Server.SLASH + entity.getName();
dfb7d3 117       } else {
U 118         return "Ungueltiges Objekt im Body.";
119       }
120     } else {
f70acb 121       return "Ungueltiger Elementname: " + getResString(RB_EP_LISTE);
dfb7d3 122     }
f70acb 123   }
U 124   
125   private void ablageortHinzufuegen(HttpExchange e, Ablageort ort) {
126     HttpContext c = e.getHttpContext();
127     String ctx = c.getPath();
128     c.getServer().createContext(ctx + ort.getUrl(),  
129           new ListFileHandler(new File(ort.getOrt()).getAbsolutePath(), conf));  
dfb7d3 130   }
8d7d35 131   
2b5c60 132   private boolean loeschen(HttpExchange e) {
5f70da 133     String path = e.getRequestURI().toString();
0e9cd3 134     String[] elems = path.split(Server.SLASH);
5f70da 135     String type = elems[elems.length - 2];
U 136     String elemName = elems[elems.length - 1];
f70acb 137     FileStorage fs = new FileStorage(conf);
0c14c0 138     if(type.equalsIgnoreCase(FileStorage.ST_ABLAGEORT)) {
U 139       // im laufenden Server den Context entfernen
140       Entity entity = fs.read(type, elemName);
141       if(entity instanceof Ablageort) {
142         Ablageort ablageort = (Ablageort) entity;
f70acb 143         //App.getServer().ablageortEntfernen(ablageort.getUrl());      
U 144         e.getHttpContext().getServer().removeContext(ablageort.getUrl());
0c14c0 145       }
U 146     }
2b5c60 147     return fs.delete(type, elemName);
U 148   }
149   
d769f3 150   private String lesen(HttpExchange e) throws IOException, InterruptedException {
2b5c60 151     String path = e.getRequestURI().toString();
0e9cd3 152     String[] elems = path.split(Server.SLASH);
f70acb 153     FileStorage fs = new FileStorage(conf);
0e9cd3 154     if(path.endsWith(Server.SLASH)) {
f45e20 155       List list = null;
f70acb 156       if(elems[elems.length - 1].equalsIgnoreCase(getResString(RB_EP_LISTE_ALLES))) {
f45e20 157         String type = elems[elems.length - 2];
U 158         logger.fine(type);
d769f3 159         if(type.equalsIgnoreCase(ST_GERAET)) {
757ace 160           list = collectDeviceStatus(fs, type);
29be41 161           Gson gson = new Gson();
U 162           Object o = gson.fromJson(bodyLesen(e), fs.typeFromName(type).getType());
757ace 163           return gson.toJson(list);
d769f3 164         }
f70acb 165       } else if(elems[elems.length - 1].equalsIgnoreCase(getResString(RB_EP_LISTE))) {
a29f5c 166         String type = elems[elems.length - 2];
U 167         logger.fine(type);
168         list = fs.list(type);
d027b5 169         if(type.equalsIgnoreCase(ST_ABLAGEORT)) {
1c3232 170           //list.add("Livestreams");
d027b5 171         }
f45e20 172       } else {
U 173         String type = elems[elems.length - 1];
174         logger.fine(type);
175         list = fs.listObjects(type);
176       }
a43e1a 177       return jsonWithEnclosingType(list);
2b5c60 178     } else {
U 179       String type = elems[elems.length - 2];
180       String elemName = elems[elems.length - 1];
181       return fs.readJson(type, elemName);
182     }
a43e1a 183   }
b379f5 184   
8d7d35 185   @Override
U 186   public String get(HttpExchange e) {
d769f3 187     try {
U 188       return lesen(e);
189     } catch (IOException | InterruptedException ex) {
190       Logger.getLogger(StorageHandler.class.getName()).log(Level.SEVERE, null, ex);
191       return ex.getLocalizedMessage();
192     }
8d7d35 193   }
U 194
195   @Override
196   public String post(HttpExchange e) {
197     return "nicht unterstuetzt";
198   }
199
200   @Override
201   public boolean delete(HttpExchange e) {
202     return loeschen(e);
b379f5 203   }
757ace 204   
U 205   private List collectDeviceStatus(Storage fs, String type) throws IOException, InterruptedException {
206     List list = fs.listObjects(type);
207     List<Geraet> newList = new ArrayList();
208     Iterator<Entity> i = list.iterator();
209     while (i.hasNext()) {
210       Entity entity = i.next();
211       if (entity instanceof Geraet) {
212         Geraet g = (Geraet) entity;
213         String statusurl = g.getStatusUrl();
214         logger.info(statusurl);
215
216         HttpRequest request = HttpRequest.newBuilder()
217                 .uri(URI.create(statusurl))
218                 .build();
219         HttpClient client = HttpClient.newBuilder()
220                 .version(Version.HTTP_1_1)
221                 .followRedirects(Redirect.NORMAL)
222                 .connectTimeout(Duration.ofSeconds(20))
223                 //.proxy(ProxySelector.of(new InetSocketAddress("proxy.example.com", 80)))
224                 //.authenticator(Authenticator.getDefault())
225                 .build();
226         HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
227         logger.finer(Integer.toString(response.statusCode()));
228         logger.finer(response.body());
229         // {"ison":false,"has_timer":false,"overpower":false}
230         String[] parts = response.body().split(",")[0].split(":");
231         logger.finer("ison: " + parts[1]);
5c6214 232         g.setStatus(Boolean.parseBoolean(parts[1]));
757ace 233         newList.add(g);
U 234       }
235     }
236     return newList;
237   }
b379f5 238 }