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