9031
|
1 package test; |
|
2 |
|
3 /** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde |
|
4 * Software engineering by |
|
5 * Björnsen Beratende Ingenieure GmbH |
|
6 * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt |
|
7 * |
|
8 * This file is Free Software under the GNU AGPL (>=v3) |
|
9 * and comes with ABSOLUTELY NO WARRANTY! Check out the |
|
10 * documentation coming with Dive4Elements River for details. |
|
11 */ |
|
12 |
|
13 import java.io.File; |
|
14 import java.io.FileNotFoundException; |
|
15 import java.io.FileOutputStream; |
|
16 import java.io.IOException; |
|
17 import java.io.InputStream; |
|
18 import java.io.InputStreamReader; |
|
19 import java.net.URL; |
|
20 import java.util.ArrayList; |
|
21 import java.util.HashMap; |
|
22 import java.util.List; |
|
23 |
|
24 import org.apache.commons.io.FileUtils; |
|
25 import org.apache.commons.io.IOUtils; |
|
26 import org.dive4elements.artifacts.common.ArtifactNamespaceContext; |
|
27 import org.dive4elements.artifacts.common.utils.ClientProtocolUtils; |
|
28 import org.dive4elements.artifacts.httpclient.exceptions.ConnectionException; |
|
29 import org.dive4elements.artifacts.httpclient.http.HttpClient; |
|
30 import org.dive4elements.artifacts.httpclient.http.HttpClientImpl; |
|
31 import org.dive4elements.artifacts.httpclient.http.response.DocumentResponseHandler; |
|
32 import org.dive4elements.artifacts.httpclient.utils.XMLUtils; |
|
33 import org.dive4elements.river.client.client.ui.NilDatacageTwinPanelInfo; |
|
34 import org.dive4elements.river.client.client.ui.RecommandationUtils; |
|
35 import org.dive4elements.river.client.server.AdvanceServiceImpl; |
|
36 import org.dive4elements.river.client.server.ArtifactHelper; |
|
37 import org.dive4elements.river.client.server.CollectionHelper; |
|
38 import org.dive4elements.river.client.server.CreateCollectionServiceImpl; |
|
39 import org.dive4elements.river.client.server.FLYSArtifactCreator; |
|
40 import org.dive4elements.river.client.server.FeedServiceImpl; |
|
41 import org.dive4elements.river.client.server.LoadArtifactServiceImpl; |
|
42 import org.dive4elements.river.client.server.auth.DefaultUser; |
|
43 import org.dive4elements.river.client.server.auth.User; |
|
44 import org.dive4elements.river.client.server.auth.UserClient; |
|
45 import org.dive4elements.river.client.shared.exceptions.ServerException; |
|
46 import org.dive4elements.river.client.shared.model.Artifact; |
|
47 import org.dive4elements.river.client.shared.model.Collection; |
|
48 import org.dive4elements.river.client.shared.model.Data; |
|
49 import org.dive4elements.river.client.shared.model.DataItem; |
|
50 import org.dive4elements.river.client.shared.model.DefaultCollection; |
|
51 import org.dive4elements.river.client.shared.model.DefaultDataItem; |
9127
|
52 import org.dive4elements.river.client.shared.model.OutputMode; |
9031
|
53 import org.dive4elements.river.client.shared.model.Recommendation; |
|
54 import org.dive4elements.river.client.shared.model.StringOptionsData; |
|
55 import org.junit.Assert; |
|
56 import org.w3c.dom.Document; |
|
57 import org.w3c.dom.Element; |
|
58 |
9127
|
59 import test.BerechnungsartenTester.CalcMode; |
|
60 import test.BerechnungsartenTester.FilenameMapper; |
|
61 import test.BerechnungsartenTester.River; |
|
62 |
9031
|
63 /** |
|
64 * @author Domenico Nardi Tironi |
|
65 * |
|
66 */ |
9127
|
67 public abstract class ModuleRunner { |
|
68 |
|
69 public enum Infotype { |
|
70 sinfo |
|
71 } |
9031
|
72 |
|
73 private final String serverUrl = "http://localhost:8181"; |
|
74 private final String locale = "de"; |
|
75 private final HttpClient client; |
|
76 |
|
77 private static final String exportFileDir = "D:" + File.separator; |
9127
|
78 private static final String IGNORE_ERSTELLDATUM = "# Datum der Erstellung"; |
|
79 private static final String IGNORE_FLYS_VERSION = "# FLYS-Version:"; |
|
80 private static final String IGNORE_BEARBEITER = "# Bearbeiter:"; |
9031
|
81 |
|
82 private final String username; |
|
83 private final String password; |
9127
|
84 private final Infotype infotype; |
9031
|
85 private final String userUuid; |
|
86 private Collection collection; |
|
87 private Artifact artifact; |
9127
|
88 private final FilenameMapper fileName; |
|
89 |
|
90 // common attributes |
|
91 private final CalcMode calcMode; |
|
92 private final double from; |
|
93 private final double to; |
|
94 private final River river; |
9031
|
95 |
|
96 private final List<String> pairIds = new ArrayList<String>(); |
|
97 |
9127
|
98 public ModuleRunner(final String username, final String password, final Infotype infotype, final CalcMode sinfoCalcFlowDepth, |
|
99 final FilenameMapper helloWorldFile, final double from, final double to, final River beispielfluss) throws ConnectionException, ServerException { |
|
100 // common attributes (evtl. doch in subklassen, evtl. Zwischenhierarchiestufe einführen |
|
101 |
|
102 this.calcMode = sinfoCalcFlowDepth; |
|
103 this.river = beispielfluss; |
|
104 this.from = from; |
|
105 this.to = to; |
|
106 |
9031
|
107 this.username = username; |
|
108 this.password = password; |
|
109 this.infotype = infotype; |
9127
|
110 this.fileName = helloWorldFile; |
9031
|
111 |
|
112 // init |
|
113 this.client = new HttpClientImpl(this.serverUrl, this.locale); |
|
114 this.userUuid = makeUserUuid(); |
|
115 this.collection = getCollection(); |
|
116 this.artifact = getArtifact(); |
|
117 } |
|
118 |
|
119 private String makeUserUuid() throws ConnectionException { |
|
120 final User user = new DefaultUser(this.username, this.password, null, false, new ArrayList<String>(), new ArrayList<String>()); |
|
121 final UserClient userClient = new UserClient(this.serverUrl); |
|
122 Element userElement; |
|
123 |
|
124 userElement = userClient.findUser(user); |
|
125 return userElement.getAttributeNS(ArtifactNamespaceContext.NAMESPACE_URI, "uuid"); |
|
126 |
|
127 } |
|
128 |
|
129 protected final Artifact getArtifact() throws ServerException, ConnectionException { |
|
130 if (this.artifact == null) { |
9127
|
131 this.artifact = ArtifactHelper.createArtifact(this.serverUrl, this.locale, this.infotype.name(), null); |
9031
|
132 setCollection(CollectionHelper.addArtifact(getCollection(), this.artifact, this.serverUrl, this.locale)); // wichtig; sorgt für Persistenz |
|
133 } |
|
134 return this.artifact; |
|
135 } |
|
136 |
|
137 private Collection getCollection() throws ConnectionException { |
|
138 |
|
139 if (this.collection == null) { |
|
140 // lazy-Loading |
|
141 final Document create = ClientProtocolUtils.newCreateCollectionDocument(null); |
|
142 final Document doc = (Document) this.client.createCollection(create, this.userUuid, new DocumentResponseHandler()); |
|
143 final String uuid = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_UUID, ArtifactNamespaceContext.INSTANCE); |
|
144 final String ttlStr = XMLUtils.xpathString(doc, CreateCollectionServiceImpl.XPATH_COLLECTION_TTL, ArtifactNamespaceContext.INSTANCE); |
|
145 this.collection = new DefaultCollection(uuid, Long.valueOf(ttlStr), uuid); |
|
146 } |
|
147 return this.collection; |
|
148 |
|
149 } |
|
150 |
9127
|
151 private final void setCollection(final Collection collection) { |
9031
|
152 this.collection = collection; |
|
153 } |
|
154 |
9127
|
155 private final void setArtifact(final Artifact artifact) { |
9031
|
156 this.artifact = artifact; |
|
157 } |
|
158 |
|
159 public abstract void runTest(final boolean exportToFile) throws ConnectionException, ServerException, IOException; |
|
160 |
|
161 protected final void describeCollection() throws ConnectionException { |
|
162 |
|
163 final String uuid = getCollection().identifier(); |
|
164 final Document describe = ClientProtocolUtils.newDescribeCollectionDocument(uuid); |
|
165 final Document response = (Document) this.client.doCollectionAction(describe, uuid, new DocumentResponseHandler()); |
|
166 final Collection c = CollectionHelper.parseCollection(response); |
|
167 setCollection(c); |
|
168 |
|
169 } |
|
170 |
|
171 protected final void feedAndGo(final Data[] data, final int reachableStateIndex) throws ConnectionException, ServerException { |
|
172 feed(data); |
9127
|
173 advance(getReachableStateByIndex(getArtifact(), reachableStateIndex)); // reachablestate könnte auch String sein. |
|
174 |
9031
|
175 } |
|
176 |
9127
|
177 private final String getReachableStateByIndex(final Artifact artifact, final int index) { |
9031
|
178 |
|
179 final String[] states = artifact.getArtifactDescription().getReachableStates(); |
|
180 if (states != null) { |
|
181 if (states.length > index) { |
|
182 return states[index]; |
|
183 } else { |
|
184 return states[0]; |
|
185 } |
|
186 } else { |
|
187 return ""; |
|
188 } |
|
189 } |
|
190 |
9127
|
191 private final void feed(final Data[] data) throws ServerException, ConnectionException { |
9031
|
192 final Document feed = ClientProtocolUtils.newFeedDocument(getArtifact().getUuid(), getArtifact().getHash(), createKVP(data)); |
|
193 final Document description = (Document) this.client.feed( |
|
194 new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), feed, |
|
195 new DocumentResponseHandler()); |
|
196 |
|
197 final String result = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE); |
|
198 |
|
199 if (result == null || !result.equals(FeedServiceImpl.OPERATION_FAILURE)) { |
|
200 setArtifact((Artifact) new FLYSArtifactCreator().create(description)); |
|
201 } else if (result != null && result.equals(FeedServiceImpl.OPERATION_FAILURE)) { |
|
202 final String msg = XMLUtils.xpathString(description, FeedServiceImpl.XPATH_RESULT_MSG, ArtifactNamespaceContext.INSTANCE); |
|
203 throw new ServerException(msg); |
|
204 } |
|
205 } |
|
206 |
9127
|
207 private final String[][] createKVP(final Data[] data) { |
9031
|
208 if (data != null) { |
|
209 final String[][] kvp = new String[data.length][]; |
|
210 |
|
211 int i = 0; |
|
212 |
|
213 for (final Data d : data) { |
|
214 // final DataItem[] items = d.getItems(); |
|
215 final String key = d.getLabel(); |
|
216 final String value = d.getStringValue(); |
|
217 |
|
218 kvp[i++] = new String[] { key, value }; |
|
219 } |
|
220 |
|
221 return kvp; |
|
222 } |
|
223 return null; |
|
224 } |
|
225 |
9127
|
226 private final void advance(final String target) throws ConnectionException, ServerException { |
9031
|
227 final Document advance = ClientProtocolUtils.newAdvanceDocument(getArtifact().getUuid(), getArtifact().getHash(), target); |
|
228 final Document description = (Document) this.client.advance( |
|
229 new org.dive4elements.artifacts.httpclient.objects.Artifact(getArtifact().getUuid(), getArtifact().getHash()), advance, |
|
230 new DocumentResponseHandler()); |
|
231 |
|
232 if (description == null) { |
|
233 throw new ServerException(AdvanceServiceImpl.ERROR_ADVANCE_ARTIFACT); |
|
234 } |
|
235 |
|
236 final String result = XMLUtils.xpathString(description, AdvanceServiceImpl.XPATH_RESULT, ArtifactNamespaceContext.INSTANCE); |
|
237 |
|
238 if (result == null || !result.equals(AdvanceServiceImpl.OPERATION_FAILURE)) { |
|
239 setArtifact((Artifact) new FLYSArtifactCreator().create(description)); |
|
240 } |
|
241 } |
|
242 |
|
243 protected final Artifact[] loadMany(final Recommendation[] recoms, final String factory) throws ServerException, ConnectionException { |
|
244 final ArrayList<Artifact> artifacts = new ArrayList<Artifact>(); |
|
245 final HashMap<Recommendation, Artifact> cloneMap = new HashMap<Recommendation, Artifact>(); |
|
246 |
|
247 for (final Recommendation recom : recoms) { |
|
248 |
|
249 final Artifact prevClone = cloneMap.get(recom); |
|
250 if (prevClone != null) { |
|
251 |
|
252 artifacts.add(prevClone); |
|
253 } else { |
|
254 // Not already cloned. |
|
255 final String realFactory = factory != null ? factory : recom.getFactory(); |
|
256 |
|
257 final Artifact clone = ArtifactHelper.createArtifact(this.serverUrl, this.locale, realFactory, recom); |
|
258 |
|
259 if (clone != null) { |
|
260 final Collection c = CollectionHelper.addArtifact(getCollection(), clone, this.serverUrl, this.locale); |
|
261 |
|
262 if (c != null) { |
|
263 artifacts.add(clone); |
|
264 // Remember we cloned a recommendation like this. |
|
265 cloneMap.put(recom, clone); |
|
266 } else { |
|
267 throw new ServerException(LoadArtifactServiceImpl.ERROR_LOAD_ARTIFACT); |
|
268 } |
|
269 } |
|
270 } |
|
271 } |
|
272 return artifacts.toArray(new Artifact[artifacts.size()]); |
|
273 |
|
274 } |
|
275 |
|
276 /// ExportServiceImpl |
9127
|
277 protected final void doGet(final String mode, final boolean exportToFile) throws IOException { |
9031
|
278 |
|
279 final String type = "csv"; |
|
280 |
|
281 final String enc = "windows-1252";// req.getParameter("encoding"); |
|
282 |
9127
|
283 final URL expectedResource = getClass().getResource(this.fileName.getFilename()); |
9031
|
284 final Document attr = null; |
|
285 final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr); |
|
286 |
|
287 final InputStream response = this.client.collectionOut(request, getCollection().identifier(), mode); |
|
288 |
|
289 final String actual = deleteErstelldatum(IOUtils.toString(response, "UTF-8")); |
|
290 |
|
291 final String expected = deleteErstelldatum(FileUtils.readFileToString(new File(expectedResource.getFile()), enc)); |
|
292 |
|
293 // if (!actual.equals(expected)) { |
|
294 if (exportToFile) { |
|
295 doGetWriteToDisk(mode); // TODO: WENN der Test negativ ausfällt, Datei abspeichern -> Diskussion |
|
296 } |
|
297 Assert.assertEquals(actual, expected); |
|
298 |
|
299 } |
|
300 |
9127
|
301 private final String deleteErstelldatum(final String input) { |
9031
|
302 String result = ""; |
|
303 final String[] lines = input.split(System.lineSeparator()); |
|
304 for (final String line : lines) { |
9127
|
305 if (!line.contains(ModuleRunner.IGNORE_ERSTELLDATUM) && !line.contains(ModuleRunner.IGNORE_FLYS_VERSION) |
|
306 && !line.contains(ModuleRunner.IGNORE_BEARBEITER)) { |
9031
|
307 result = result + line + System.lineSeparator(); |
|
308 } |
|
309 } |
|
310 return result; |
|
311 } |
|
312 |
9127
|
313 public final void doGetWriteToDisk(final String mode) throws FileNotFoundException, IOException { |
9031
|
314 |
|
315 final String name = mode; |
|
316 final String type = "csv"; |
|
317 |
9127
|
318 final String fn = name + System.currentTimeMillis() + "." + type; |
9031
|
319 final String enc = "windows-1252"; |
|
320 |
|
321 final String filepath = exportFileDir + fn; |
|
322 |
|
323 final Document attr = null; |
|
324 final Document request = ClientProtocolUtils.newOutCollectionDocument(getCollection().identifier(), mode, type, attr); |
|
325 |
|
326 final InputStream response = this.client.collectionOut(request, getCollection().identifier(), mode); |
|
327 final InputStreamReader in = new InputStreamReader(response, "UTF-8"); |
|
328 |
|
329 IOUtils.copy(in, new FileOutputStream(filepath), enc); |
|
330 |
|
331 } |
|
332 |
9127
|
333 public final void addRecommendationPair(final SimpleRecommendation rec1, final SimpleRecommendation rec2) throws ConnectionException, ServerException { |
|
334 final Recommendation recom1 = new Recommendation(rec1.getFactory(), rec1.getIds(), rec1.getTarget()); |
|
335 final Recommendation recom2 = new Recommendation(rec2.getFactory(), rec2.getIds(), rec2.getTarget()); |
9031
|
336 final Artifact[] artifacts = loadMany(new Recommendation[] { recom1, recom2 }, null); |
|
337 final String rec1String = RecommandationUtils.createDataString(artifacts[0].getUuid(), recom1, new NilDatacageTwinPanelInfo("xxxx")); |
|
338 final String rec2String = RecommandationUtils.createDataString(artifacts[1].getUuid(), recom2, new NilDatacageTwinPanelInfo("xxxx")); |
|
339 final String combinedIdNeu = rec1String + "#" + rec2String; |
|
340 this.pairIds.add(combinedIdNeu); |
|
341 } |
|
342 |
|
343 protected Data[] getPairData() { |
|
344 final Data[] data = new Data[this.pairIds.size()]; |
|
345 int i = 0; |
|
346 for (final String pairId : this.pairIds) { |
|
347 final Data pair = new StringOptionsData("diffids", "diffids", new DataItem[] { new DefaultDataItem(pairId, pairId, pairId) }); |
|
348 data[i] = pair; |
|
349 i++; |
|
350 } |
|
351 return data; |
|
352 } |
9127
|
353 |
|
354 protected final void selectCalcMode() throws ConnectionException, ServerException { |
|
355 |
|
356 /* Select CalcMode */ |
|
357 // final DataList calcModes = getArtifact().getArtifactDescription().getCurrentData(); // AUSWAHL-Möglichkeiten |
|
358 // final DataItem minMaxFlowdepth = calcModes.get(0).getItems()[2]; // CalcMode |
|
359 final String calcmodeStr = this.calcMode.name(); |
|
360 final Data dataCalcMode = new StringOptionsData("calculation_mode", "calculation_mode", |
|
361 new DataItem[] { new DefaultDataItem(calcmodeStr, calcmodeStr, calcmodeStr) }); |
|
362 feedAndGo(new Data[] { dataCalcMode }, 0); |
|
363 } |
|
364 |
|
365 protected final void selectRange() throws ConnectionException, ServerException { |
|
366 final String fromStr = String.valueOf(this.from); |
|
367 final String toStr = String.valueOf(this.to); |
|
368 final Data dataFrom = new StringOptionsData("ld_from", "ld_from", new DataItem[] { new DefaultDataItem(fromStr, fromStr, fromStr) }); |
|
369 final Data dataTo = new StringOptionsData("ld_to", "ld_to", new DataItem[] { new DefaultDataItem(toStr, toStr, toStr) }); |
|
370 final Data[] rangeFromToDetermined = new Data[] { dataFrom, dataTo }; |
|
371 |
|
372 feedAndGo(rangeFromToDetermined, 0); |
|
373 } |
|
374 |
|
375 // private final void seletMaxRange() throws ConnectionException, ServerException { |
|
376 // final DataList list = getArtifact().getArtifactDescription().getCurrentData(); |
|
377 // final Data[] rangeMax = new Data[] { list.get(0), list.get(1) }; |
|
378 // feedAndGo(rangeMax, 0); |
|
379 // } |
|
380 |
|
381 protected final void selectRiver() throws ConnectionException, ServerException { |
|
382 final String riverStr = this.river.name(); |
|
383 final Data data = new StringOptionsData("river", "river", new DataItem[] { new DefaultDataItem(riverStr, riverStr, riverStr) }); |
|
384 feedAndGo(new Data[] { data }, 0); |
|
385 } |
|
386 |
|
387 protected final void export(final boolean exportToFile) throws IOException, ServerException { |
|
388 final OutputMode[] modes = getArtifact().getArtifactDescription().getOutputModes(); // TODO: CHECK IF THIS WORKS ALSO FOR FUTURE CALC_MODES |
|
389 if (modes != null) { |
|
390 final OutputMode mode = modes[1]; |
|
391 doGet(mode.getName(), exportToFile); |
|
392 } |
|
393 } |
|
394 |
9031
|
395 } |