From 89cdda50e7ba7f74891f444ac222b9777f463239 Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Thu, 24 Sep 2020 14:40:43 +0300 Subject: [PATCH 01/20] migration(micronauts): servlets migrated to controllers --- Dockerfile | 4 + build.gradle | 77 +++++- gradle.properties | 3 +- micronaut-cli.yml | 6 + src/main/java/org/terasology/Application.java | 10 + .../java/org/terasology/web/JettyMain.java | 29 +- .../terasology/web/model/ModuleListModel.java | 6 +- .../web/model/ModuleListModelImpl.java | 43 ++- ...AboutServlet.java => AboutController.java} | 32 +-- .../terasology/web/servlet/ModuleServlet.java | 248 +++++++++--------- .../terasology/web/servlet/ServerForm.java | 61 +++++ .../terasology/web/servlet/ServerServlet.java | 128 +++++---- src/main/resources/application.yml | 11 + .../resources/static}/css/bootstrap-theme.css | 0 .../static}/css/bootstrap-theme.css.map | 0 .../static}/css/bootstrap-theme.min.css | 0 .../main/resources/static}/css/bootstrap.css | 0 .../resources/static}/css/bootstrap.css.map | 0 .../resources/static}/css/bootstrap.min.css | 0 .../main/resources/static}/css/custom.css | 0 .../static}/css/jumbotron-narrow.css | 0 .../main/resources/static}/favicon.ico | Bin .../fonts/glyphicons-halflings-regular.eot | Bin .../fonts/glyphicons-halflings-regular.svg | 0 .../fonts/glyphicons-halflings-regular.ttf | Bin .../fonts/glyphicons-halflings-regular.woff | Bin .../fonts/glyphicons-halflings-regular.woff2 | Bin .../main/resources/static}/img/flags/ad.png | Bin .../main/resources/static}/img/flags/ae.png | Bin .../main/resources/static}/img/flags/af.png | Bin .../main/resources/static}/img/flags/ag.png | Bin .../main/resources/static}/img/flags/ai.png | Bin .../main/resources/static}/img/flags/al.png | Bin .../main/resources/static}/img/flags/am.png | Bin .../main/resources/static}/img/flags/an.png | Bin .../main/resources/static}/img/flags/ao.png | Bin .../main/resources/static}/img/flags/ar.png | Bin .../main/resources/static}/img/flags/as.png | Bin .../main/resources/static}/img/flags/at.png | Bin .../main/resources/static}/img/flags/au.png | Bin .../main/resources/static}/img/flags/aw.png | Bin .../main/resources/static}/img/flags/ax.png | Bin .../main/resources/static}/img/flags/az.png | Bin .../main/resources/static}/img/flags/ba.png | Bin .../main/resources/static}/img/flags/bb.png | Bin .../main/resources/static}/img/flags/bd.png | Bin .../main/resources/static}/img/flags/be.png | Bin .../main/resources/static}/img/flags/bf.png | Bin .../main/resources/static}/img/flags/bg.png | Bin .../main/resources/static}/img/flags/bh.png | Bin .../main/resources/static}/img/flags/bi.png | Bin .../main/resources/static}/img/flags/bj.png | Bin .../main/resources/static}/img/flags/bm.png | Bin .../main/resources/static}/img/flags/bn.png | Bin .../main/resources/static}/img/flags/bo.png | Bin .../main/resources/static}/img/flags/br.png | Bin .../main/resources/static}/img/flags/bs.png | Bin .../main/resources/static}/img/flags/bt.png | Bin .../main/resources/static}/img/flags/bv.png | Bin .../main/resources/static}/img/flags/bw.png | Bin .../main/resources/static}/img/flags/by.png | Bin .../main/resources/static}/img/flags/bz.png | Bin .../main/resources/static}/img/flags/ca.png | Bin .../resources/static}/img/flags/catalonia.png | Bin .../main/resources/static}/img/flags/cc.png | Bin .../main/resources/static}/img/flags/cd.png | Bin .../main/resources/static}/img/flags/cf.png | Bin .../main/resources/static}/img/flags/cg.png | Bin .../main/resources/static}/img/flags/ch.png | Bin .../main/resources/static}/img/flags/ci.png | Bin .../main/resources/static}/img/flags/ck.png | Bin .../main/resources/static}/img/flags/cl.png | Bin .../main/resources/static}/img/flags/cm.png | Bin .../main/resources/static}/img/flags/cn.png | Bin .../main/resources/static}/img/flags/co.png | Bin .../main/resources/static}/img/flags/cr.png | Bin .../main/resources/static}/img/flags/cs.png | Bin .../main/resources/static}/img/flags/cu.png | Bin .../main/resources/static}/img/flags/cv.png | Bin .../main/resources/static}/img/flags/cx.png | Bin .../main/resources/static}/img/flags/cy.png | Bin .../main/resources/static}/img/flags/cz.png | Bin .../main/resources/static}/img/flags/de.png | Bin .../main/resources/static}/img/flags/dj.png | Bin .../main/resources/static}/img/flags/dk.png | Bin .../main/resources/static}/img/flags/dm.png | Bin .../main/resources/static}/img/flags/do.png | Bin .../main/resources/static}/img/flags/dz.png | Bin .../main/resources/static}/img/flags/ec.png | Bin .../main/resources/static}/img/flags/ee.png | Bin .../main/resources/static}/img/flags/eg.png | Bin .../main/resources/static}/img/flags/eh.png | Bin .../resources/static}/img/flags/england.png | Bin .../main/resources/static}/img/flags/er.png | Bin .../main/resources/static}/img/flags/es.png | Bin .../main/resources/static}/img/flags/et.png | Bin .../static}/img/flags/europeanunion.png | Bin .../main/resources/static}/img/flags/fam.png | Bin .../main/resources/static}/img/flags/fi.png | Bin .../main/resources/static}/img/flags/fj.png | Bin .../main/resources/static}/img/flags/fk.png | Bin .../main/resources/static}/img/flags/fm.png | Bin .../main/resources/static}/img/flags/fo.png | Bin .../main/resources/static}/img/flags/fr.png | Bin .../main/resources/static}/img/flags/ga.png | Bin .../main/resources/static}/img/flags/gb.png | Bin .../main/resources/static}/img/flags/gd.png | Bin .../main/resources/static}/img/flags/ge.png | Bin .../main/resources/static}/img/flags/gf.png | Bin .../main/resources/static}/img/flags/gh.png | Bin .../main/resources/static}/img/flags/gi.png | Bin .../main/resources/static}/img/flags/gl.png | Bin .../main/resources/static}/img/flags/gm.png | Bin .../main/resources/static}/img/flags/gn.png | Bin .../main/resources/static}/img/flags/gp.png | Bin .../main/resources/static}/img/flags/gq.png | Bin .../main/resources/static}/img/flags/gr.png | Bin .../main/resources/static}/img/flags/gs.png | Bin .../main/resources/static}/img/flags/gt.png | Bin .../main/resources/static}/img/flags/gu.png | Bin .../main/resources/static}/img/flags/gw.png | Bin .../main/resources/static}/img/flags/gy.png | Bin .../main/resources/static}/img/flags/hk.png | Bin .../main/resources/static}/img/flags/hm.png | Bin .../main/resources/static}/img/flags/hn.png | Bin .../main/resources/static}/img/flags/hr.png | Bin .../main/resources/static}/img/flags/ht.png | Bin .../main/resources/static}/img/flags/hu.png | Bin .../main/resources/static}/img/flags/id.png | Bin .../main/resources/static}/img/flags/ie.png | Bin .../main/resources/static}/img/flags/il.png | Bin .../main/resources/static}/img/flags/in.png | Bin .../main/resources/static}/img/flags/io.png | Bin .../main/resources/static}/img/flags/iq.png | Bin .../main/resources/static}/img/flags/ir.png | Bin .../main/resources/static}/img/flags/is.png | Bin .../main/resources/static}/img/flags/it.png | Bin .../main/resources/static}/img/flags/jm.png | Bin .../main/resources/static}/img/flags/jo.png | Bin .../main/resources/static}/img/flags/jp.png | Bin .../main/resources/static}/img/flags/ke.png | Bin .../main/resources/static}/img/flags/kg.png | Bin .../main/resources/static}/img/flags/kh.png | Bin .../main/resources/static}/img/flags/ki.png | Bin .../main/resources/static}/img/flags/km.png | Bin .../main/resources/static}/img/flags/kn.png | Bin .../main/resources/static}/img/flags/kp.png | Bin .../main/resources/static}/img/flags/kr.png | Bin .../main/resources/static}/img/flags/kw.png | Bin .../main/resources/static}/img/flags/ky.png | Bin .../main/resources/static}/img/flags/kz.png | Bin .../main/resources/static}/img/flags/la.png | Bin .../main/resources/static}/img/flags/lb.png | Bin .../main/resources/static}/img/flags/lc.png | Bin .../main/resources/static}/img/flags/li.png | Bin .../main/resources/static}/img/flags/lk.png | Bin .../main/resources/static}/img/flags/lr.png | Bin .../main/resources/static}/img/flags/ls.png | Bin .../main/resources/static}/img/flags/lt.png | Bin .../main/resources/static}/img/flags/lu.png | Bin .../main/resources/static}/img/flags/lv.png | Bin .../main/resources/static}/img/flags/ly.png | Bin .../main/resources/static}/img/flags/ma.png | Bin .../main/resources/static}/img/flags/mc.png | Bin .../main/resources/static}/img/flags/md.png | Bin .../main/resources/static}/img/flags/me.png | Bin .../main/resources/static}/img/flags/mg.png | Bin .../main/resources/static}/img/flags/mh.png | Bin .../main/resources/static}/img/flags/mk.png | Bin .../main/resources/static}/img/flags/ml.png | Bin .../main/resources/static}/img/flags/mm.png | Bin .../main/resources/static}/img/flags/mn.png | Bin .../main/resources/static}/img/flags/mo.png | Bin .../main/resources/static}/img/flags/mp.png | Bin .../main/resources/static}/img/flags/mq.png | Bin .../main/resources/static}/img/flags/mr.png | Bin .../main/resources/static}/img/flags/ms.png | Bin .../main/resources/static}/img/flags/mt.png | Bin .../main/resources/static}/img/flags/mu.png | Bin .../main/resources/static}/img/flags/mv.png | Bin .../main/resources/static}/img/flags/mw.png | Bin .../main/resources/static}/img/flags/mx.png | Bin .../main/resources/static}/img/flags/my.png | Bin .../main/resources/static}/img/flags/mz.png | Bin .../main/resources/static}/img/flags/na.png | Bin .../main/resources/static}/img/flags/nc.png | Bin .../main/resources/static}/img/flags/ne.png | Bin .../main/resources/static}/img/flags/nf.png | Bin .../main/resources/static}/img/flags/ng.png | Bin .../main/resources/static}/img/flags/ni.png | Bin .../main/resources/static}/img/flags/nl.png | Bin .../main/resources/static}/img/flags/no.png | Bin .../main/resources/static}/img/flags/np.png | Bin .../main/resources/static}/img/flags/nr.png | Bin .../main/resources/static}/img/flags/nu.png | Bin .../main/resources/static}/img/flags/nz.png | Bin .../main/resources/static}/img/flags/om.png | Bin .../main/resources/static}/img/flags/pa.png | Bin .../main/resources/static}/img/flags/pe.png | Bin .../main/resources/static}/img/flags/pf.png | Bin .../main/resources/static}/img/flags/pg.png | Bin .../main/resources/static}/img/flags/ph.png | Bin .../main/resources/static}/img/flags/pk.png | Bin .../main/resources/static}/img/flags/pl.png | Bin .../main/resources/static}/img/flags/pm.png | Bin .../main/resources/static}/img/flags/pn.png | Bin .../main/resources/static}/img/flags/pr.png | Bin .../main/resources/static}/img/flags/ps.png | Bin .../main/resources/static}/img/flags/pt.png | Bin .../main/resources/static}/img/flags/pw.png | Bin .../main/resources/static}/img/flags/py.png | Bin .../main/resources/static}/img/flags/qa.png | Bin .../main/resources/static}/img/flags/re.png | Bin .../main/resources/static}/img/flags/ro.png | Bin .../main/resources/static}/img/flags/rs.png | Bin .../main/resources/static}/img/flags/ru.png | Bin .../main/resources/static}/img/flags/rw.png | Bin .../main/resources/static}/img/flags/sa.png | Bin .../main/resources/static}/img/flags/sb.png | Bin .../main/resources/static}/img/flags/sc.png | Bin .../resources/static}/img/flags/scotland.png | Bin .../main/resources/static}/img/flags/sd.png | Bin .../main/resources/static}/img/flags/se.png | Bin .../main/resources/static}/img/flags/sg.png | Bin .../main/resources/static}/img/flags/sh.png | Bin .../main/resources/static}/img/flags/si.png | Bin .../main/resources/static}/img/flags/sj.png | Bin .../main/resources/static}/img/flags/sk.png | Bin .../main/resources/static}/img/flags/sl.png | Bin .../main/resources/static}/img/flags/sm.png | Bin .../main/resources/static}/img/flags/sn.png | Bin .../main/resources/static}/img/flags/so.png | Bin .../main/resources/static}/img/flags/sr.png | Bin .../main/resources/static}/img/flags/st.png | Bin .../main/resources/static}/img/flags/sv.png | Bin .../main/resources/static}/img/flags/sy.png | Bin .../main/resources/static}/img/flags/sz.png | Bin .../main/resources/static}/img/flags/tc.png | Bin .../main/resources/static}/img/flags/td.png | Bin .../main/resources/static}/img/flags/tf.png | Bin .../main/resources/static}/img/flags/tg.png | Bin .../main/resources/static}/img/flags/th.png | Bin .../main/resources/static}/img/flags/tj.png | Bin .../main/resources/static}/img/flags/tk.png | Bin .../main/resources/static}/img/flags/tl.png | Bin .../main/resources/static}/img/flags/tm.png | Bin .../main/resources/static}/img/flags/tn.png | Bin .../main/resources/static}/img/flags/to.png | Bin .../main/resources/static}/img/flags/tr.png | Bin .../main/resources/static}/img/flags/tt.png | Bin .../main/resources/static}/img/flags/tv.png | Bin .../main/resources/static}/img/flags/tw.png | Bin .../main/resources/static}/img/flags/tz.png | Bin .../main/resources/static}/img/flags/ua.png | Bin .../main/resources/static}/img/flags/ug.png | Bin .../main/resources/static}/img/flags/um.png | Bin .../main/resources/static}/img/flags/us.png | Bin .../main/resources/static}/img/flags/uy.png | Bin .../main/resources/static}/img/flags/uz.png | Bin .../main/resources/static}/img/flags/va.png | Bin .../main/resources/static}/img/flags/vc.png | Bin .../main/resources/static}/img/flags/ve.png | Bin .../main/resources/static}/img/flags/vg.png | Bin .../main/resources/static}/img/flags/vi.png | Bin .../main/resources/static}/img/flags/vn.png | Bin .../main/resources/static}/img/flags/vu.png | Bin .../resources/static}/img/flags/wales.png | Bin .../main/resources/static}/img/flags/wf.png | Bin .../main/resources/static}/img/flags/ws.png | Bin .../main/resources/static}/img/flags/ye.png | Bin .../main/resources/static}/img/flags/yt.png | Bin .../main/resources/static}/img/flags/za.png | Bin .../main/resources/static}/img/flags/zm.png | Bin .../main/resources/static}/img/flags/zw.png | Bin .../resources/static}/img/gooey_sweet_32.png | Bin .../static}/img/sweet-gooey-smallish.png | Bin {web => src/main/resources/static}/index.html | 0 .../main/resources/views}/about.ftl | 0 .../main/resources/views}/add.ftl | 0 .../resources/views}/edit-server-controls.ftl | 0 .../main/resources/views}/edit.ftl | 0 .../main/resources/views}/footer.ftl | 0 .../main/resources/views}/metainfo.ftl | 0 .../main/resources/views}/module-info.ftl | 0 .../main/resources/views}/module-list.ftl | 0 .../main/resources/views}/navigation.ftl | 0 .../main/resources/views}/server-list.ftl | 0 .../master/WebServerBasedTests.java | 21 +- 288 files changed, 397 insertions(+), 282 deletions(-) create mode 100644 Dockerfile create mode 100644 micronaut-cli.yml create mode 100644 src/main/java/org/terasology/Application.java rename src/main/java/org/terasology/web/servlet/{AboutServlet.java => AboutController.java} (63%) create mode 100644 src/main/java/org/terasology/web/servlet/ServerForm.java create mode 100644 src/main/resources/application.yml rename {web => src/main/resources/static}/css/bootstrap-theme.css (100%) rename {web => src/main/resources/static}/css/bootstrap-theme.css.map (100%) rename {web => src/main/resources/static}/css/bootstrap-theme.min.css (100%) rename {web => src/main/resources/static}/css/bootstrap.css (100%) rename {web => src/main/resources/static}/css/bootstrap.css.map (100%) rename {web => src/main/resources/static}/css/bootstrap.min.css (100%) rename {web => src/main/resources/static}/css/custom.css (100%) rename {web => src/main/resources/static}/css/jumbotron-narrow.css (100%) rename {web => src/main/resources/static}/favicon.ico (100%) rename {web => src/main/resources/static}/fonts/glyphicons-halflings-regular.eot (100%) rename {web => src/main/resources/static}/fonts/glyphicons-halflings-regular.svg (100%) rename {web => src/main/resources/static}/fonts/glyphicons-halflings-regular.ttf (100%) rename {web => src/main/resources/static}/fonts/glyphicons-halflings-regular.woff (100%) rename {web => src/main/resources/static}/fonts/glyphicons-halflings-regular.woff2 (100%) rename {web => src/main/resources/static}/img/flags/ad.png (100%) rename {web => src/main/resources/static}/img/flags/ae.png (100%) rename {web => src/main/resources/static}/img/flags/af.png (100%) rename {web => src/main/resources/static}/img/flags/ag.png (100%) rename {web => src/main/resources/static}/img/flags/ai.png (100%) rename {web => src/main/resources/static}/img/flags/al.png (100%) rename {web => src/main/resources/static}/img/flags/am.png (100%) rename {web => src/main/resources/static}/img/flags/an.png (100%) rename {web => src/main/resources/static}/img/flags/ao.png (100%) rename {web => src/main/resources/static}/img/flags/ar.png (100%) rename {web => src/main/resources/static}/img/flags/as.png (100%) rename {web => src/main/resources/static}/img/flags/at.png (100%) rename {web => src/main/resources/static}/img/flags/au.png (100%) rename {web => src/main/resources/static}/img/flags/aw.png (100%) rename {web => src/main/resources/static}/img/flags/ax.png (100%) rename {web => src/main/resources/static}/img/flags/az.png (100%) rename {web => src/main/resources/static}/img/flags/ba.png (100%) rename {web => src/main/resources/static}/img/flags/bb.png (100%) rename {web => src/main/resources/static}/img/flags/bd.png (100%) rename {web => src/main/resources/static}/img/flags/be.png (100%) rename {web => src/main/resources/static}/img/flags/bf.png (100%) rename {web => src/main/resources/static}/img/flags/bg.png (100%) rename {web => src/main/resources/static}/img/flags/bh.png (100%) rename {web => src/main/resources/static}/img/flags/bi.png (100%) rename {web => src/main/resources/static}/img/flags/bj.png (100%) rename {web => src/main/resources/static}/img/flags/bm.png (100%) rename {web => src/main/resources/static}/img/flags/bn.png (100%) rename {web => src/main/resources/static}/img/flags/bo.png (100%) rename {web => src/main/resources/static}/img/flags/br.png (100%) rename {web => src/main/resources/static}/img/flags/bs.png (100%) rename {web => src/main/resources/static}/img/flags/bt.png (100%) rename {web => src/main/resources/static}/img/flags/bv.png (100%) rename {web => src/main/resources/static}/img/flags/bw.png (100%) rename {web => src/main/resources/static}/img/flags/by.png (100%) rename {web => src/main/resources/static}/img/flags/bz.png (100%) rename {web => src/main/resources/static}/img/flags/ca.png (100%) rename {web => src/main/resources/static}/img/flags/catalonia.png (100%) rename {web => src/main/resources/static}/img/flags/cc.png (100%) rename {web => src/main/resources/static}/img/flags/cd.png (100%) rename {web => src/main/resources/static}/img/flags/cf.png (100%) rename {web => src/main/resources/static}/img/flags/cg.png (100%) rename {web => src/main/resources/static}/img/flags/ch.png (100%) rename {web => src/main/resources/static}/img/flags/ci.png (100%) rename {web => src/main/resources/static}/img/flags/ck.png (100%) rename {web => src/main/resources/static}/img/flags/cl.png (100%) rename {web => src/main/resources/static}/img/flags/cm.png (100%) rename {web => src/main/resources/static}/img/flags/cn.png (100%) rename {web => src/main/resources/static}/img/flags/co.png (100%) rename {web => src/main/resources/static}/img/flags/cr.png (100%) rename {web => src/main/resources/static}/img/flags/cs.png (100%) rename {web => src/main/resources/static}/img/flags/cu.png (100%) rename {web => src/main/resources/static}/img/flags/cv.png (100%) rename {web => src/main/resources/static}/img/flags/cx.png (100%) rename {web => src/main/resources/static}/img/flags/cy.png (100%) rename {web => src/main/resources/static}/img/flags/cz.png (100%) rename {web => src/main/resources/static}/img/flags/de.png (100%) rename {web => src/main/resources/static}/img/flags/dj.png (100%) rename {web => src/main/resources/static}/img/flags/dk.png (100%) rename {web => src/main/resources/static}/img/flags/dm.png (100%) rename {web => src/main/resources/static}/img/flags/do.png (100%) rename {web => src/main/resources/static}/img/flags/dz.png (100%) rename {web => src/main/resources/static}/img/flags/ec.png (100%) rename {web => src/main/resources/static}/img/flags/ee.png (100%) rename {web => src/main/resources/static}/img/flags/eg.png (100%) rename {web => src/main/resources/static}/img/flags/eh.png (100%) rename {web => src/main/resources/static}/img/flags/england.png (100%) rename {web => src/main/resources/static}/img/flags/er.png (100%) rename {web => src/main/resources/static}/img/flags/es.png (100%) rename {web => src/main/resources/static}/img/flags/et.png (100%) rename {web => src/main/resources/static}/img/flags/europeanunion.png (100%) rename {web => src/main/resources/static}/img/flags/fam.png (100%) rename {web => src/main/resources/static}/img/flags/fi.png (100%) rename {web => src/main/resources/static}/img/flags/fj.png (100%) rename {web => src/main/resources/static}/img/flags/fk.png (100%) rename {web => src/main/resources/static}/img/flags/fm.png (100%) rename {web => src/main/resources/static}/img/flags/fo.png (100%) rename {web => src/main/resources/static}/img/flags/fr.png (100%) rename {web => src/main/resources/static}/img/flags/ga.png (100%) rename {web => src/main/resources/static}/img/flags/gb.png (100%) rename {web => src/main/resources/static}/img/flags/gd.png (100%) rename {web => src/main/resources/static}/img/flags/ge.png (100%) rename {web => src/main/resources/static}/img/flags/gf.png (100%) rename {web => src/main/resources/static}/img/flags/gh.png (100%) rename {web => src/main/resources/static}/img/flags/gi.png (100%) rename {web => src/main/resources/static}/img/flags/gl.png (100%) rename {web => src/main/resources/static}/img/flags/gm.png (100%) rename {web => src/main/resources/static}/img/flags/gn.png (100%) rename {web => src/main/resources/static}/img/flags/gp.png (100%) rename {web => src/main/resources/static}/img/flags/gq.png (100%) rename {web => src/main/resources/static}/img/flags/gr.png (100%) rename {web => src/main/resources/static}/img/flags/gs.png (100%) rename {web => src/main/resources/static}/img/flags/gt.png (100%) rename {web => src/main/resources/static}/img/flags/gu.png (100%) rename {web => src/main/resources/static}/img/flags/gw.png (100%) rename {web => src/main/resources/static}/img/flags/gy.png (100%) rename {web => src/main/resources/static}/img/flags/hk.png (100%) rename {web => src/main/resources/static}/img/flags/hm.png (100%) rename {web => src/main/resources/static}/img/flags/hn.png (100%) rename {web => src/main/resources/static}/img/flags/hr.png (100%) rename {web => src/main/resources/static}/img/flags/ht.png (100%) rename {web => src/main/resources/static}/img/flags/hu.png (100%) rename {web => src/main/resources/static}/img/flags/id.png (100%) rename {web => src/main/resources/static}/img/flags/ie.png (100%) rename {web => src/main/resources/static}/img/flags/il.png (100%) rename {web => src/main/resources/static}/img/flags/in.png (100%) rename {web => src/main/resources/static}/img/flags/io.png (100%) rename {web => src/main/resources/static}/img/flags/iq.png (100%) rename {web => src/main/resources/static}/img/flags/ir.png (100%) rename {web => src/main/resources/static}/img/flags/is.png (100%) rename {web => src/main/resources/static}/img/flags/it.png (100%) rename {web => src/main/resources/static}/img/flags/jm.png (100%) rename {web => src/main/resources/static}/img/flags/jo.png (100%) rename {web => src/main/resources/static}/img/flags/jp.png (100%) rename {web => src/main/resources/static}/img/flags/ke.png (100%) rename {web => src/main/resources/static}/img/flags/kg.png (100%) rename {web => src/main/resources/static}/img/flags/kh.png (100%) rename {web => src/main/resources/static}/img/flags/ki.png (100%) rename {web => src/main/resources/static}/img/flags/km.png (100%) rename {web => src/main/resources/static}/img/flags/kn.png (100%) rename {web => src/main/resources/static}/img/flags/kp.png (100%) rename {web => src/main/resources/static}/img/flags/kr.png (100%) rename {web => src/main/resources/static}/img/flags/kw.png (100%) rename {web => src/main/resources/static}/img/flags/ky.png (100%) rename {web => src/main/resources/static}/img/flags/kz.png (100%) rename {web => src/main/resources/static}/img/flags/la.png (100%) rename {web => src/main/resources/static}/img/flags/lb.png (100%) rename {web => src/main/resources/static}/img/flags/lc.png (100%) rename {web => src/main/resources/static}/img/flags/li.png (100%) rename {web => src/main/resources/static}/img/flags/lk.png (100%) rename {web => src/main/resources/static}/img/flags/lr.png (100%) rename {web => src/main/resources/static}/img/flags/ls.png (100%) rename {web => src/main/resources/static}/img/flags/lt.png (100%) rename {web => src/main/resources/static}/img/flags/lu.png (100%) rename {web => src/main/resources/static}/img/flags/lv.png (100%) rename {web => src/main/resources/static}/img/flags/ly.png (100%) rename {web => src/main/resources/static}/img/flags/ma.png (100%) rename {web => src/main/resources/static}/img/flags/mc.png (100%) rename {web => src/main/resources/static}/img/flags/md.png (100%) rename {web => src/main/resources/static}/img/flags/me.png (100%) rename {web => src/main/resources/static}/img/flags/mg.png (100%) rename {web => src/main/resources/static}/img/flags/mh.png (100%) rename {web => src/main/resources/static}/img/flags/mk.png (100%) rename {web => src/main/resources/static}/img/flags/ml.png (100%) rename {web => src/main/resources/static}/img/flags/mm.png (100%) rename {web => src/main/resources/static}/img/flags/mn.png (100%) rename {web => src/main/resources/static}/img/flags/mo.png (100%) rename {web => src/main/resources/static}/img/flags/mp.png (100%) rename {web => src/main/resources/static}/img/flags/mq.png (100%) rename {web => src/main/resources/static}/img/flags/mr.png (100%) rename {web => src/main/resources/static}/img/flags/ms.png (100%) rename {web => src/main/resources/static}/img/flags/mt.png (100%) rename {web => src/main/resources/static}/img/flags/mu.png (100%) rename {web => src/main/resources/static}/img/flags/mv.png (100%) rename {web => src/main/resources/static}/img/flags/mw.png (100%) rename {web => src/main/resources/static}/img/flags/mx.png (100%) rename {web => src/main/resources/static}/img/flags/my.png (100%) rename {web => src/main/resources/static}/img/flags/mz.png (100%) rename {web => src/main/resources/static}/img/flags/na.png (100%) rename {web => src/main/resources/static}/img/flags/nc.png (100%) rename {web => src/main/resources/static}/img/flags/ne.png (100%) rename {web => src/main/resources/static}/img/flags/nf.png (100%) rename {web => src/main/resources/static}/img/flags/ng.png (100%) rename {web => src/main/resources/static}/img/flags/ni.png (100%) rename {web => src/main/resources/static}/img/flags/nl.png (100%) rename {web => src/main/resources/static}/img/flags/no.png (100%) rename {web => src/main/resources/static}/img/flags/np.png (100%) rename {web => src/main/resources/static}/img/flags/nr.png (100%) rename {web => src/main/resources/static}/img/flags/nu.png (100%) rename {web => src/main/resources/static}/img/flags/nz.png (100%) rename {web => src/main/resources/static}/img/flags/om.png (100%) rename {web => src/main/resources/static}/img/flags/pa.png (100%) rename {web => src/main/resources/static}/img/flags/pe.png (100%) rename {web => src/main/resources/static}/img/flags/pf.png (100%) rename {web => src/main/resources/static}/img/flags/pg.png (100%) rename {web => src/main/resources/static}/img/flags/ph.png (100%) rename {web => src/main/resources/static}/img/flags/pk.png (100%) rename {web => src/main/resources/static}/img/flags/pl.png (100%) rename {web => src/main/resources/static}/img/flags/pm.png (100%) rename {web => src/main/resources/static}/img/flags/pn.png (100%) rename {web => src/main/resources/static}/img/flags/pr.png (100%) rename {web => src/main/resources/static}/img/flags/ps.png (100%) rename {web => src/main/resources/static}/img/flags/pt.png (100%) rename {web => src/main/resources/static}/img/flags/pw.png (100%) rename {web => src/main/resources/static}/img/flags/py.png (100%) rename {web => src/main/resources/static}/img/flags/qa.png (100%) rename {web => src/main/resources/static}/img/flags/re.png (100%) rename {web => src/main/resources/static}/img/flags/ro.png (100%) rename {web => src/main/resources/static}/img/flags/rs.png (100%) rename {web => src/main/resources/static}/img/flags/ru.png (100%) rename {web => src/main/resources/static}/img/flags/rw.png (100%) rename {web => src/main/resources/static}/img/flags/sa.png (100%) rename {web => src/main/resources/static}/img/flags/sb.png (100%) rename {web => src/main/resources/static}/img/flags/sc.png (100%) rename {web => src/main/resources/static}/img/flags/scotland.png (100%) rename {web => src/main/resources/static}/img/flags/sd.png (100%) rename {web => src/main/resources/static}/img/flags/se.png (100%) rename {web => src/main/resources/static}/img/flags/sg.png (100%) rename {web => src/main/resources/static}/img/flags/sh.png (100%) rename {web => src/main/resources/static}/img/flags/si.png (100%) rename {web => src/main/resources/static}/img/flags/sj.png (100%) rename {web => src/main/resources/static}/img/flags/sk.png (100%) rename {web => src/main/resources/static}/img/flags/sl.png (100%) rename {web => src/main/resources/static}/img/flags/sm.png (100%) rename {web => src/main/resources/static}/img/flags/sn.png (100%) rename {web => src/main/resources/static}/img/flags/so.png (100%) rename {web => src/main/resources/static}/img/flags/sr.png (100%) rename {web => src/main/resources/static}/img/flags/st.png (100%) rename {web => src/main/resources/static}/img/flags/sv.png (100%) rename {web => src/main/resources/static}/img/flags/sy.png (100%) rename {web => src/main/resources/static}/img/flags/sz.png (100%) rename {web => src/main/resources/static}/img/flags/tc.png (100%) rename {web => src/main/resources/static}/img/flags/td.png (100%) rename {web => src/main/resources/static}/img/flags/tf.png (100%) rename {web => src/main/resources/static}/img/flags/tg.png (100%) rename {web => src/main/resources/static}/img/flags/th.png (100%) rename {web => src/main/resources/static}/img/flags/tj.png (100%) rename {web => src/main/resources/static}/img/flags/tk.png (100%) rename {web => src/main/resources/static}/img/flags/tl.png (100%) rename {web => src/main/resources/static}/img/flags/tm.png (100%) rename {web => src/main/resources/static}/img/flags/tn.png (100%) rename {web => src/main/resources/static}/img/flags/to.png (100%) rename {web => src/main/resources/static}/img/flags/tr.png (100%) rename {web => src/main/resources/static}/img/flags/tt.png (100%) rename {web => src/main/resources/static}/img/flags/tv.png (100%) rename {web => src/main/resources/static}/img/flags/tw.png (100%) rename {web => src/main/resources/static}/img/flags/tz.png (100%) rename {web => src/main/resources/static}/img/flags/ua.png (100%) rename {web => src/main/resources/static}/img/flags/ug.png (100%) rename {web => src/main/resources/static}/img/flags/um.png (100%) rename {web => src/main/resources/static}/img/flags/us.png (100%) rename {web => src/main/resources/static}/img/flags/uy.png (100%) rename {web => src/main/resources/static}/img/flags/uz.png (100%) rename {web => src/main/resources/static}/img/flags/va.png (100%) rename {web => src/main/resources/static}/img/flags/vc.png (100%) rename {web => src/main/resources/static}/img/flags/ve.png (100%) rename {web => src/main/resources/static}/img/flags/vg.png (100%) rename {web => src/main/resources/static}/img/flags/vi.png (100%) rename {web => src/main/resources/static}/img/flags/vn.png (100%) rename {web => src/main/resources/static}/img/flags/vu.png (100%) rename {web => src/main/resources/static}/img/flags/wales.png (100%) rename {web => src/main/resources/static}/img/flags/wf.png (100%) rename {web => src/main/resources/static}/img/flags/ws.png (100%) rename {web => src/main/resources/static}/img/flags/ye.png (100%) rename {web => src/main/resources/static}/img/flags/yt.png (100%) rename {web => src/main/resources/static}/img/flags/za.png (100%) rename {web => src/main/resources/static}/img/flags/zm.png (100%) rename {web => src/main/resources/static}/img/flags/zw.png (100%) rename {web => src/main/resources/static}/img/gooey_sweet_32.png (100%) rename {web => src/main/resources/static}/img/sweet-gooey-smallish.png (100%) rename {web => src/main/resources/static}/index.html (100%) rename {templates => src/main/resources/views}/about.ftl (100%) rename {templates => src/main/resources/views}/add.ftl (100%) rename {templates => src/main/resources/views}/edit-server-controls.ftl (100%) rename {templates => src/main/resources/views}/edit.ftl (100%) rename {templates => src/main/resources/views}/footer.ftl (100%) rename {templates => src/main/resources/views}/metainfo.ftl (100%) rename {templates => src/main/resources/views}/module-info.ftl (100%) rename {templates => src/main/resources/views}/module-list.ftl (100%) rename {templates => src/main/resources/views}/navigation.ftl (100%) rename {templates => src/main/resources/views}/server-list.ftl (100%) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..63b9bc8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM openjdk:14-alpine +COPY build/libs/meta-server-*-all.jar meta-server.jar +EXPOSE 8080 +CMD ["java", "-Dcom.sun.management.jmxremote", "-Xmx128m", "-jar", "meta-server.jar"] \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8aa2a81..9e12a9d 100644 --- a/build.gradle +++ b/build.gradle @@ -6,17 +6,21 @@ plugins { id 'pmd' id 'checkstyle' id 'com.github.spotbugs' version '4.5.0' + + id "com.diffplug.eclipse.apt" version "3.22.0" + id "com.github.johnrengelman.shadow" version "6.0.0" } apply from: 'config/gradle/versioning.gradle' -mainClassName = "org.terasology.web.JettyMain" +mainClassName = "org.terasology.Application" applicationName = "meta-server" group = 'org.terasology.web' repositories { mavenCentral() + jcenter() maven { name "Terasology Artifactory" @@ -29,13 +33,47 @@ ext { jettyVersion = '9.4.6.v20170531' } +java { + sourceCompatibility = JavaVersion.toVersion('11') + targetCompatibility = JavaVersion.toVersion('11') +} + def codeMetricsDir = "${buildDir}/codeMetrics" configurations { codeMetrics + // for dependencies that are needed for development only + developmentOnly } dependencies { + /* Micronauts start*/ + annotationProcessor(platform("io.micronaut:micronaut-bom:$micronautVersion")) + annotationProcessor("io.micronaut:micronaut-inject-java") + annotationProcessor("io.micronaut:micronaut-validation") + implementation(platform("io.micronaut:micronaut-bom:$micronautVersion")) + implementation("io.micronaut:micronaut-inject") + implementation("io.micronaut:micronaut-validation") + implementation("io.micronaut:micronaut-runtime") + implementation("javax.annotation:javax.annotation-api") + implementation("io.micronaut:micronaut-http-server-netty") + implementation("io.micronaut.views:micronaut-views-freemarker") + implementation("io.micronaut:micronaut-http-client") + implementation("io.micronaut.sql:micronaut-jdbc-hikari") + implementation("io.micronaut.sql:micronaut-jooq") + runtimeOnly("ch.qos.logback:logback-classic") + runtimeOnly("org.postgresql:postgresql") + testAnnotationProcessor(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")) + testAnnotationProcessor("io.micronaut:micronaut-inject-java") + testImplementation(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")) + testImplementation("org.junit.jupiter:junit-jupiter-api") + testImplementation("io.micronaut.test:micronaut-test-junit5") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") + + testImplementation(platform("org.testcontainers:testcontainers-bom:1.14.3")) + testRuntimeOnly("org.testcontainers:postgresql") + /* Micronauts end*/ + implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: jettyVersion implementation group: 'org.eclipse.jetty', name: 'jetty-servlets', version: jettyVersion implementation 'javax.servlet:javax.servlet-api:3.1.0' @@ -43,7 +81,6 @@ dependencies { implementation 'com.google.code.findbugs:jsr305:3.0.0' implementation 'org.glassfish.jersey.containers:jersey-container-jetty-servlet:2.22.1' - implementation 'org.glassfish.jersey.ext:jersey-mvc-freemarker:2.22.1' implementation 'com.google.code.gson:gson:2.4' implementation 'com.google.guava:guava:18.0' @@ -53,7 +90,7 @@ dependencies { implementation 'com.squareup.retrofit:retrofit:1.9.0' - implementation 'org.slf4j:slf4j-api:1.7.13' + implementation 'org.slf4j:slf4j-api:1.7.30' implementation 'com.zaxxer:HikariCP:2.4.1' @@ -64,6 +101,7 @@ dependencies { testImplementation 'com.jcabi:jcabi-matchers:1.4' testImplementation 'junit:junit:4.12' testImplementation 'com.h2database:h2:1.4.190' + testImplementation 'org.slf4j:slf4j-api:1.7.30' runtimeOnly group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.3' @@ -73,6 +111,8 @@ dependencies { codeMetrics group: 'org.terasology.config', name: 'codemetrics', version: '1.3.2', ext: 'zip' } +test.classpath += configurations.developmentOnly + task unpackConfig(type: Sync, dependsOn: configurations.codeMetrics) { from zipTree(configurations.codeMetrics.singleFile) into codeMetricsDir @@ -99,7 +139,38 @@ spotbugs { excludeFilter = resources.text.fromFile("${codeMetricsDir}/findbugs/findbugs-exclude.xml").asFile() } + +tasks.withType(JavaCompile) { + options.encoding = "UTF-8" + options.compilerArgs.addAll([ + '-parameters', + // enables incremental compilation + '-Amicronaut.processing.incremental=true', + '-Amicronaut.processing.annotations=org.terasology.*', + "-Amicronaut.processing.group=$project.group", + "-Amicronaut.processing.module=$project.name", + ]) +} + +shadowJar { + mergeServiceFiles() +} + +tasks.withType(JavaExec) { + classpath += configurations.developmentOnly + jvmArgs('-XX:TieredStopAtLevel=1', '-Dcom.sun.management.jmxremote') + if (gradle.startParameter.continuous) { + systemProperties( + 'micronaut.io.watch.restart':'true', + 'micronaut.io.watch.enabled':'true', + "micronaut.io.watch.paths":"src/main" + ) + } +} + + test { + useJUnitPlatform() // ignoreFailures: Specifies whether the build should break when the verifications performed by this task fail. ignoreFailures = true diff --git a/gradle.properties b/gradle.properties index a8a802c..4032aa5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ #Mon Apr 20 18:44:42 CEST 2015 -version=2.7.1-SNAPSHOT +version=3.0.0 versioneye.projectkey=maven2_master_server_1 versioneye.projectid=55352d6edc39815abf0007ad +micronautVersion=2.0.3 diff --git a/micronaut-cli.yml b/micronaut-cli.yml new file mode 100644 index 0000000..16ea4a2 --- /dev/null +++ b/micronaut-cli.yml @@ -0,0 +1,6 @@ +applicationType: default +defaultPackage: org.terasology +testFramework: junit +sourceLanguage: java +buildTool: gradle +features: [ annotation-api, app-name, docker, file-watch, gradle, http-client, java, java-application, jdbc-hikari, jooq, junit, logback, netty-server, postgres, readme, shade, testcontainers, views-freemarker, yaml ] diff --git a/src/main/java/org/terasology/Application.java b/src/main/java/org/terasology/Application.java new file mode 100644 index 0000000..71b3e75 --- /dev/null +++ b/src/main/java/org/terasology/Application.java @@ -0,0 +1,10 @@ +package org.terasology; + +import io.micronaut.runtime.Micronaut; + +public class Application { + + public static void main(String[] args) { + Micronaut.run(Application.class, args); + } +} diff --git a/src/main/java/org/terasology/web/JettyMain.java b/src/main/java/org/terasology/web/JettyMain.java index 8563ef4..695a246 100644 --- a/src/main/java/org/terasology/web/JettyMain.java +++ b/src/main/java/org/terasology/web/JettyMain.java @@ -16,12 +16,8 @@ package org.terasology.web; -import java.net.URI; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.EnumSet; -import java.util.Locale; - +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.HandlerList; @@ -31,7 +27,6 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlets.CrossOriginFilter; import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.server.mvc.freemarker.FreemarkerMvcFeature; import org.glassfish.jersey.servlet.ServletContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,14 +39,13 @@ import org.terasology.web.model.ModuleListModelImpl; import org.terasology.web.model.ServerListModel; import org.terasology.web.model.ServerListModelImpl; -import org.terasology.web.servlet.AboutServlet; -import org.terasology.web.servlet.ModuleServlet; -import org.terasology.web.servlet.ServerServlet; - -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; import javax.servlet.DispatcherType; +import java.net.URI; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.EnumSet; +import java.util.Locale; /** @@ -138,17 +132,11 @@ public static void main(String[] args) throws Exception { DataBase dataBase = new JooqDatabase(ds, geoService); ServerListModel serverListModel = new ServerListModelImpl(dataBase, "servers", secret); - Server server = createServer(port.intValue(), - new AboutServlet(), - new ServerServlet(serverListModel), // the server list servlet - new ModuleServlet(moduleListModel)); // the module list servlet - - server.start(); logger.info("Server started on port {}!", port); new Thread(moduleListModel::updateAllModules).start(); - server.join(); + // server.join(); } } @@ -171,7 +159,6 @@ public static Server createServer(int port, Object... servlets) throws Exception ResourceConfig rc = new ResourceConfig(); rc.register(new GsonMessageBodyHandler()); // register JSON serializer - rc.register(FreemarkerMvcFeature.class); for (Object servlet : servlets) { rc.register(servlet); diff --git a/src/main/java/org/terasology/web/model/ModuleListModel.java b/src/main/java/org/terasology/web/model/ModuleListModel.java index f2b59fd..c9196be 100644 --- a/src/main/java/org/terasology/web/model/ModuleListModel.java +++ b/src/main/java/org/terasology/web/model/ModuleListModel.java @@ -16,13 +16,13 @@ package org.terasology.web.model; -import java.util.Collection; -import java.util.Set; - import org.terasology.module.Module; import org.terasology.naming.Name; import org.terasology.naming.Version; +import java.util.Collection; +import java.util.Set; + /** * Provides a list of modules. */ diff --git a/src/main/java/org/terasology/web/model/ModuleListModelImpl.java b/src/main/java/org/terasology/web/model/ModuleListModelImpl.java index b7d9c9b..f9eaff1 100644 --- a/src/main/java/org/terasology/web/model/ModuleListModelImpl.java +++ b/src/main/java/org/terasology/web/model/ModuleListModelImpl.java @@ -16,45 +16,34 @@ package org.terasology.web.model; -import java.io.File; -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import javax.annotation.concurrent.ThreadSafe; - +import com.google.common.io.Files; +import io.micronaut.context.annotation.Value; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.module.DependencyResolver; import org.terasology.module.Module; -import org.terasology.module.ModuleMetadata; -import org.terasology.module.ModuleMetadataJsonAdapter; -import org.terasology.module.ModuleRegistry; -import org.terasology.module.RemoteModuleExtension; -import org.terasology.module.ResolutionResult; -import org.terasology.module.TableModuleRegistry; +import org.terasology.module.*; import org.terasology.naming.Name; import org.terasology.naming.Version; import org.terasology.web.artifactory.ArtifactInfo; import org.terasology.web.artifactory.ArtifactRepository; -import com.google.common.io.Files; +import javax.annotation.concurrent.ThreadSafe; +import javax.inject.Singleton; +import java.io.File; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Provides a list of modules. */ @ThreadSafe +@Singleton public class ModuleListModelImpl implements ModuleListModel { private static final Logger logger = LoggerFactory.getLogger(ModuleListModelImpl.class); @@ -71,7 +60,7 @@ public class ModuleListModelImpl implements ModuleListModel { private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); - public ModuleListModelImpl(Path cacheFolder) { + public ModuleListModelImpl(@Value("${meta-server.cacheFolder}") Path cacheFolder) { this(cacheFolder, new ZipExtractor("module.txt", "engine-module.txt")); } diff --git a/src/main/java/org/terasology/web/servlet/AboutServlet.java b/src/main/java/org/terasology/web/servlet/AboutController.java similarity index 63% rename from src/main/java/org/terasology/web/servlet/AboutServlet.java rename to src/main/java/org/terasology/web/servlet/AboutController.java index dccf1dd..26e2204 100644 --- a/src/main/java/org/terasology/web/servlet/AboutServlet.java +++ b/src/main/java/org/terasology/web/servlet/AboutController.java @@ -16,34 +16,30 @@ package org.terasology.web.servlet; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -import org.glassfish.jersey.server.mvc.Viewable; +import io.micronaut.core.util.CollectionUtils; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.MediaType; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Produces; +import io.micronaut.views.View; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.web.version.VersionInfo; -import com.google.common.collect.ImmutableMap; - /** * Show the about html page. */ -@Path("/") -public class AboutServlet { +@Controller() +public class AboutController { - private static final Logger logger = LoggerFactory.getLogger(AboutServlet.class); + private static final Logger logger = LoggerFactory.getLogger(AboutController.class); - @GET - @Path("home") + @View("about") @Produces(MediaType.TEXT_HTML) - public Viewable about() { + @Get(value = "home") + public HttpResponse about() { logger.info("Requested about as HTML"); - ImmutableMap dataModel = ImmutableMap.builder() - .put("version", VersionInfo.getVersion()) - .build(); - return new Viewable("/about.ftl", dataModel); + return HttpResponse.ok(CollectionUtils.mapOf("version", VersionInfo.getVersion())); } } diff --git a/src/main/java/org/terasology/web/servlet/ModuleServlet.java b/src/main/java/org/terasology/web/servlet/ModuleServlet.java index 723ef19..8d111c7 100644 --- a/src/main/java/org/terasology/web/servlet/ModuleServlet.java +++ b/src/main/java/org/terasology/web/servlet/ModuleServlet.java @@ -16,31 +16,17 @@ package org.terasology.web.servlet; -import java.io.OutputStreamWriter; -import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; -import javax.ws.rs.core.StreamingOutput; -import javax.ws.rs.core.UriInfo; - -import org.glassfish.jersey.server.mvc.Viewable; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Multimap; +import com.google.common.collect.TreeMultimap; +import com.google.gson.stream.JsonWriter; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.MediaType; +import io.micronaut.http.annotation.*; +import io.micronaut.http.server.util.HttpHostResolver; +import io.micronaut.views.View; +import io.micronaut.web.router.RouteBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.module.Module; @@ -50,19 +36,19 @@ import org.terasology.naming.Name; import org.terasology.naming.Version; import org.terasology.naming.exception.VersionParseException; -import org.terasology.web.version.VersionInfo; import org.terasology.web.model.ModuleListModel; import org.terasology.web.model.jenkins.Job; +import org.terasology.web.version.VersionInfo; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Multimap; -import com.google.common.collect.TreeMultimap; -import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.net.URI; +import java.util.*; /** * TODO Type description */ -@Path("/modules/") +@Controller("/modules/") public class ModuleServlet { private static final Logger logger = LoggerFactory.getLogger(ModuleServlet.class); @@ -76,43 +62,51 @@ public class ModuleServlet { */ private final Comparator versionComparator = (m1, m2) -> m2.getVersion().compareTo(m1.getVersion()); + private final HttpHostResolver httpHostResolver; + private final RouteBuilder.UriNamingStrategy uriNamingStrategy; - public ModuleServlet(ModuleListModel model) { + public ModuleServlet( + HttpHostResolver httpHostResolver, + RouteBuilder.UriNamingStrategy uriNamingStrategy, + ModuleListModel model + ) { this.model = model; + this.httpHostResolver = httpHostResolver; + this.uriNamingStrategy = uriNamingStrategy; this.metadataWriter = new ModuleMetadataJsonAdapter(); for (RemoteModuleExtension ext : RemoteModuleExtension.values()) { metadataWriter.registerExtension(ext.getKey(), ext.getValueType()); } } - @GET - @Path("list") + @Get("list") @Produces(MediaType.APPLICATION_JSON) - public Response list() { + public HttpResponse list() { logger.info("Requested module list as json"); - - StreamingOutput stream = os -> { - List sortedModuleIds = new ArrayList<>(model.getModuleIds()); - sortedModuleIds.sort(null); - try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8))) { - writer.beginArray(); - writer.setIndent(" "); // enable pretty printing - for (Name name : sortedModuleIds) { - for (Module module : model.getModuleVersions(name)) { - ModuleMetadata meta = module.getMetadata(); - metadataWriter.write(meta, writer); - } + StringWriter response = new StringWriter(); + List sortedModuleIds = new ArrayList<>(model.getModuleIds()); + sortedModuleIds.sort(null); + try (JsonWriter writer = new JsonWriter(response)) { + writer.beginArray(); + writer.setIndent(" "); // enable pretty printing + for (Name name : sortedModuleIds) { + for (Module module : model.getModuleVersions(name)) { + ModuleMetadata meta = module.getMetadata(); + metadataWriter.write(meta, writer); } - writer.endArray(); } - }; - return Response.ok(stream).build(); + writer.endArray(); + } catch (IOException e) { + logger.error("Cannot create module list", e); + return HttpResponse.serverError(); + } + return HttpResponse.ok(response.toString()); } - @GET - @Path("show") + @Get("show") + @View("module-list") @Produces(MediaType.TEXT_HTML) - public Viewable show() { + public HttpResponse show() { logger.info("Requested module list as HTML"); Set names = model.getModuleIds(); @@ -128,58 +122,58 @@ public Viewable show() { .put("items", map.asMap()) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/module-list.ftl", dataModel); + return HttpResponse.ok(dataModel); } - @GET - @Path("list/latest") + @Get("list/latest") @Produces(MediaType.APPLICATION_JSON) - public Response listLatest() { + public HttpResponse listLatest() { logger.info("Requested lastest info as json"); - - StreamingOutput stream = os -> { - List sortedModuleIds = new ArrayList<>(model.getModuleIds()); - sortedModuleIds.sort(null); - try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8))) { - writer.beginArray(); - writer.setIndent(" "); // enable pretty printing - for (Name name : sortedModuleIds) { - Module module = model.getLatestModuleVersion(name); - ModuleMetadata meta = module.getMetadata(); - metadataWriter.write(meta, writer); - } - writer.endArray(); + StringWriter response = new StringWriter(); + List sortedModuleIds = new ArrayList<>(model.getModuleIds()); + sortedModuleIds.sort(null); + try (JsonWriter writer = new JsonWriter(response)) { + writer.beginArray(); + writer.setIndent(" "); // enable pretty printing + for (Name name : sortedModuleIds) { + Module module = model.getLatestModuleVersion(name); + ModuleMetadata meta = module.getMetadata(); + metadataWriter.write(meta, writer); } - }; - return Response.ok(stream).build(); + writer.endArray(); + } catch (IOException e) { + logger.error("Cannot create module list", e); + return HttpResponse.serverError(); + } + return HttpResponse.ok(response.toString()); } - @GET - @Path("list/{module}") + @Get("list/{module}") @Produces(MediaType.APPLICATION_JSON) - public Response listModule(@PathParam("module") String moduleName) { + public HttpResponse listModule(@PathVariable("module") String moduleName) { logger.info("Requested module versions as json"); Name name = new Name(moduleName); - - StreamingOutput stream = os -> { - try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8))) { - writer.beginArray(); - writer.setIndent(" "); // enable pretty printing - for (Module module : model.getModuleVersions(name)) { - ModuleMetadata meta = module.getMetadata(); - metadataWriter.write(meta, writer); - } - writer.endArray(); + StringWriter response = new StringWriter(); + try (JsonWriter writer = new JsonWriter(response)) { + writer.beginArray(); + writer.setIndent(" "); // enable pretty printing + for (Module module : model.getModuleVersions(name)) { + ModuleMetadata meta = module.getMetadata(); + metadataWriter.write(meta, writer); } - }; - return Response.ok(stream).build(); + writer.endArray(); + } catch (IOException e) { + logger.error("Cannot create module list", e); + return HttpResponse.serverError(); + } + return HttpResponse.ok(response.toString()); } - @GET - @Path("show/{module}") + @Get("show/{module}") + @View("module-list") @Produces(MediaType.TEXT_HTML) - public Viewable showModule(@PathParam("module") String module) { + public HttpResponse showModule(@PathVariable("module") String module) { logger.info("Requested module versions as HTML"); Name name = new Name(module); @@ -194,72 +188,68 @@ public Viewable showModule(@PathParam("module") String module) { .put("moduleId", module) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/module-list.ftl", dataModel); + return HttpResponse.ok(dataModel); } - @GET - @Path("list/{module}/latest") + @Get("list/{module}/latest") @Produces(MediaType.TEXT_HTML) - public Response listModuleLatest(@Context UriInfo uriInfo, @PathParam("module") String module) { + public HttpResponse listModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { + URI uri = httpRequest.getUri(); logger.info("Requested lastest module info as HTML"); - int pathLen = uriInfo.getPath().length(); - String path = uriInfo.getPath().substring(0, pathLen - "latest".length()); + int pathLen = uri.getPath().length(); + String path = uri.getPath().substring(0, pathLen - "latest".length()); Module latest = model.getLatestModuleVersion(new Name(module)); if (latest == null) { - return Response.status(Status.NOT_FOUND).build(); + return HttpResponse.notFound(); } String ver = latest.getVersion().toString(); - URI redirect = URI.create(uriInfo.getBaseUri() + path + ver); - return Response.temporaryRedirect(redirect).build(); + URI redirect = URI.create(path + ver); + return HttpResponse.temporaryRedirect(redirect); } - @GET - @Path("list/{module}/{version}") + @Get("list/{module}/{version}") @Produces(MediaType.APPLICATION_JSON) - public Response listModuleVersion(@PathParam("module") String moduleName, @PathParam("version") String versionStr) { + public HttpResponse listModuleVersion(@PathVariable("module") String moduleName, @PathVariable("version") String versionStr) { logger.info("Requested single module info as json"); try { Version version = new Version(versionStr); Module module = model.getModule(new Name(moduleName), version); if (module == null) { - return Response.status(Status.NOT_FOUND).build(); + return HttpResponse.notFound(); } ModuleMetadata meta = module.getMetadata(); + StringWriter response = new StringWriter(); - StreamingOutput stream = os -> { - try (OutputStreamWriter writer = new OutputStreamWriter(os, StandardCharsets.UTF_8)) { - metadataWriter.write(meta, writer); - } - }; - return Response.ok(stream).build(); + metadataWriter.write(meta, response); + return HttpResponse.ok(response.toString()); } catch (VersionParseException e) { logger.warn("Invalid version for module '{}' specified: {}", moduleName, versionStr); - return Response.status(Status.NOT_FOUND).build(); + return HttpResponse.notFound(); } } - @GET - @Path("show/{module}/latest") + @Get("show/{module}/latest") @Produces(MediaType.TEXT_HTML) - public Response showModuleLatest(@Context UriInfo uriInfo, @PathParam("module") String module) { + public HttpResponse showModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { + URI uriInfo = httpRequest.getUri(); logger.info("Requested lastest module info as HTML"); int pathLen = uriInfo.getPath().length(); String path = uriInfo.getPath().substring(0, pathLen - "latest".length()); Module latest = model.getLatestModuleVersion(new Name(module)); if (latest == null) { - return Response.status(Status.NOT_FOUND).build(); + return HttpResponse.notFound(); } String ver = latest.getVersion().toString(); - URI redirect = URI.create(uriInfo.getBaseUri() + path + ver); - return Response.temporaryRedirect(redirect).build(); + URI redirect = URI.create(path + ver); + return HttpResponse.temporaryRedirect(redirect); } - @GET - @Path("show/{module}/{version}") + @Get("show/{module}/{version}") + @View("module-info") @Produces(MediaType.TEXT_HTML) - public Response showModuleVersion(@PathParam("module") String module, @PathParam("version") String version) { + public HttpResponse showModuleVersion(@PathVariable("module") String module, @PathVariable("version") String version) { logger.info("Requested module info as HTML"); try { @@ -268,7 +258,7 @@ public Response showModuleVersion(@PathParam("module") String module, @PathParam Module mod = model.getModule(moduleName, modVersion); if (mod == null) { logger.warn("No entry for module '{}' found", module); - return Response.status(Status.NOT_FOUND).build(); + return HttpResponse.notFound(); } ModuleMetadata meta = mod.getMetadata(); @@ -282,35 +272,33 @@ public Response showModuleVersion(@PathParam("module") String module, @PathParam .put("dependencies", deps) .put("version", VersionInfo.getVersion()) .build(); - return Response.ok(new Viewable("/module-info.ftl", dataModel)).build(); + return HttpResponse.ok(dataModel); } catch (VersionParseException e) { logger.warn("Invalid version for module '{}' specified: {}", module, version); - return Response.status(Status.NOT_FOUND).build(); + return HttpResponse.notFound(); } } - @POST - @Path("update") + @Post("update") @Consumes(MediaType.APPLICATION_JSON) - public Response updateModulePost(Job jobState) { + public HttpResponse updateModulePost(Job jobState) { String job = jobState.getName(); logger.info("Requested module update for {}", job); model.updateModule(new Name(job)); - return Response.ok().build(); + return HttpResponse.ok(); } - @POST - @Path("update-all") + @Post("update-all") @Consumes(MediaType.APPLICATION_JSON) - public Response updateAllModulesPost() { + public HttpResponse updateAllModulesPost() { logger.info("Requested complete module update"); new Thread(model::updateAllModules).start(); - return Response.ok().build(); + return HttpResponse.ok(); } } diff --git a/src/main/java/org/terasology/web/servlet/ServerForm.java b/src/main/java/org/terasology/web/servlet/ServerForm.java new file mode 100644 index 0000000..1ea0aad --- /dev/null +++ b/src/main/java/org/terasology/web/servlet/ServerForm.java @@ -0,0 +1,61 @@ +package org.terasology.web.servlet; + +/** + * Pojo for Server add/edit form. + */ +public class ServerForm { + private String name; + private String address; + private int port; + private String owner; + private String activeOn; + private String secret; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public String getActiveOn() { + return activeOn; + } + + public void setActiveOn(String activeOn) { + this.activeOn = activeOn; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } +} diff --git a/src/main/java/org/terasology/web/servlet/ServerServlet.java b/src/main/java/org/terasology/web/servlet/ServerServlet.java index 13ac136..67df871 100644 --- a/src/main/java/org/terasology/web/servlet/ServerServlet.java +++ b/src/main/java/org/terasology/web/servlet/ServerServlet.java @@ -16,32 +16,28 @@ package org.terasology.web.servlet; -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import javax.ws.rs.DefaultValue; -import javax.ws.rs.FormParam; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; - -import org.glassfish.jersey.server.mvc.Viewable; +import com.google.common.collect.ImmutableMap; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.MediaType; +import io.micronaut.http.annotation.*; +import io.micronaut.views.View; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.web.version.VersionInfo; import org.terasology.web.model.Result; import org.terasology.web.model.ServerEntry; import org.terasology.web.model.ServerListModel; +import org.terasology.web.version.VersionInfo; -import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.List; /** + * */ -@Path("/servers/") +@Controller("/servers/") public class ServerServlet { private static final Logger logger = LoggerFactory.getLogger(ServerServlet.class); @@ -52,22 +48,22 @@ public ServerServlet(ServerListModel model) { this.model = model; } - @GET - @Path("show") + @Get("show") + @View("server-list") @Produces(MediaType.TEXT_HTML) - public Viewable show() { + public HttpResponse show() { logger.info("Requested server list as HTML"); ImmutableMap dataModel = ImmutableMap.builder() .put("items", list()) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/server-list.ftl", dataModel); + return HttpResponse.ok(dataModel); } - @GET - @Path("add") + @Get("add") + @View("add") @Produces(MediaType.TEXT_HTML) - public Viewable add() { + public HttpResponse add() { logger.info("Requested add as HTML"); ImmutableMap dataModel = ImmutableMap.builder() .put("name", "") @@ -77,13 +73,13 @@ public Viewable add() { .put("active", false) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/add.ftl", dataModel); + return HttpResponse.ok(dataModel); } - @GET - @Path("edit") + @Get("edit") + @View("edit") @Produces(MediaType.TEXT_HTML) - public Viewable edit(@QueryParam("index") @DefaultValue("-1") int index) throws IOException { + public HttpResponse edit(@QueryValue(value = "index", defaultValue = "-1") int index) throws IOException { List servers = model.getServers(); if (index < 0 || index >= servers.size()) { @@ -101,11 +97,10 @@ public Viewable edit(@QueryParam("index") @DefaultValue("-1") int index) throws .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/edit.ftl", dataModel); + return HttpResponse.ok(dataModel); } - @GET - @Path("list") + @Get("list") @Produces(MediaType.APPLICATION_JSON) public Object list() { logger.info("Requested server list"); @@ -117,16 +112,15 @@ public Object list() { } } - @POST - @Path("add") + @Post("add") + @View("add") @Produces(MediaType.TEXT_HTML) - public Viewable add(@FormParam("name") String name, @FormParam("address") String address, @FormParam("port") int port, - @FormParam("owner") String owner, @FormParam("active") String activeOn, @FormParam("secret") String secret) { + public HttpResponse add(@Body ServerForm serverForm) throws URISyntaxException { - boolean active = "on".equals(activeOn); - logger.info("Requested addition: name: {}, address: {}, port:{}, owner:{}, active:{}", name, address, port, owner, active); + boolean active = "on".equals(serverForm.getActiveOn()); + logger.info("Requested addition: name: {}, address: {}, port:{}, owner:{}, active:{}", serverForm.getName(), serverForm.getAddress(), serverForm.getPort(), serverForm.getOwner(), active); - Result response = model.addServer(name, address, port, owner, active, secret); + Result response = model.addServer(serverForm.getName(), serverForm.getAddress(), serverForm.getPort(), serverForm.getOwner(), active, serverForm.getSecret()); if (response.isSuccess()) { ImmutableMap dataModel = ImmutableMap.builder() @@ -134,76 +128,74 @@ public Viewable add(@FormParam("name") String name, @FormParam("address") String .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/server-list.ftl", dataModel); + return HttpResponse.redirect(new URI("list")); } else { ImmutableMap dataModel = ImmutableMap.builder() - .put("name", name) - .put("address", address) - .put("port", port) - .put("owner", owner) + .put("name", serverForm.getName()) + .put("address", serverForm.getAddress()) + .put("port", serverForm.getPort()) + .put("owner", serverForm.getOwner()) .put("active", active) .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/add.ftl", dataModel); + return HttpResponse.ok(dataModel); } } - @POST - @Path("remove") + @Post("remove") + @View("edit") @Produces(MediaType.TEXT_HTML) - public Viewable remove(@FormParam("name") String name, @FormParam("address") String address, @FormParam("port") int port, - @FormParam("owner") String owner, @FormParam("active") String activeOn, @FormParam("secret") String secret) { + public HttpResponse remove(@Body ServerForm serverForm) throws URISyntaxException { - boolean active = "on".equals(activeOn); - Result response = model.removeServer(address, port, secret); + boolean active = "on".equals(serverForm.getActiveOn()); + Result response = model.removeServer(serverForm.getAddress(), serverForm.getPort(), serverForm.getSecret()); if (response.isSuccess()) { ImmutableMap dataModel = ImmutableMap.builder() .put("items", list()) .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/server-list.ftl", dataModel); + return HttpResponse.redirect(new URI("list")); } else { ImmutableMap dataModel = ImmutableMap.builder() - .put("name", name) - .put("address", address) - .put("port", port) - .put("owner", owner) + .put("name", serverForm.getName()) + .put("address", serverForm.getAddress()) + .put("port", serverForm.getPort()) + .put("owner", serverForm.getOwner()) .put("active", active) .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/edit.ftl", dataModel); + return HttpResponse.ok(dataModel); } } - @POST - @Path("update") + @Post("update") + @View("edit") @Produces(MediaType.TEXT_HTML) - public Viewable update(@FormParam("name") String name, @FormParam("address") String address, @FormParam("port") int port, - @FormParam("owner") String owner, @FormParam("active") String activeOn, @FormParam("secret") String secret) { + public HttpResponse update(@Body ServerForm serverForm) throws URISyntaxException { - boolean active = "on".equals(activeOn); - Result response = model.updateServer(name, address, port, owner, active, secret); + boolean active = "on".equals(serverForm.getActiveOn()); + Result response = model.updateServer(serverForm.getName(), serverForm.getAddress(), serverForm.getPort(), serverForm.getOwner(), active, serverForm.getActiveOn()); if (response.isSuccess()) { ImmutableMap dataModel = ImmutableMap.builder() .put("items", list()) .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/server-list.ftl", dataModel); + return HttpResponse.redirect(new URI("list")); } else { ImmutableMap dataModel = ImmutableMap.builder() - .put("name", name) - .put("address", address) - .put("port", port) - .put("owner", owner) + .put("name", serverForm.getName()) + .put("address", serverForm.getAddress()) + .put("port", serverForm.getPort()) + .put("owner", serverForm.getOwner()) .put("active", active) .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new Viewable("/edit.ftl", dataModel); + return HttpResponse.ok(dataModel); } } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..ce22177 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,11 @@ +micronaut: + application: + name: meta-server + router: + static-resources: + base: + paths: + - "classpath:static" + - +meta-server: + cacheFolder: "./cache" diff --git a/web/css/bootstrap-theme.css b/src/main/resources/static/css/bootstrap-theme.css similarity index 100% rename from web/css/bootstrap-theme.css rename to src/main/resources/static/css/bootstrap-theme.css diff --git a/web/css/bootstrap-theme.css.map b/src/main/resources/static/css/bootstrap-theme.css.map similarity index 100% rename from web/css/bootstrap-theme.css.map rename to src/main/resources/static/css/bootstrap-theme.css.map diff --git a/web/css/bootstrap-theme.min.css b/src/main/resources/static/css/bootstrap-theme.min.css similarity index 100% rename from web/css/bootstrap-theme.min.css rename to src/main/resources/static/css/bootstrap-theme.min.css diff --git a/web/css/bootstrap.css b/src/main/resources/static/css/bootstrap.css similarity index 100% rename from web/css/bootstrap.css rename to src/main/resources/static/css/bootstrap.css diff --git a/web/css/bootstrap.css.map b/src/main/resources/static/css/bootstrap.css.map similarity index 100% rename from web/css/bootstrap.css.map rename to src/main/resources/static/css/bootstrap.css.map diff --git a/web/css/bootstrap.min.css b/src/main/resources/static/css/bootstrap.min.css similarity index 100% rename from web/css/bootstrap.min.css rename to src/main/resources/static/css/bootstrap.min.css diff --git a/web/css/custom.css b/src/main/resources/static/css/custom.css similarity index 100% rename from web/css/custom.css rename to src/main/resources/static/css/custom.css diff --git a/web/css/jumbotron-narrow.css b/src/main/resources/static/css/jumbotron-narrow.css similarity index 100% rename from web/css/jumbotron-narrow.css rename to src/main/resources/static/css/jumbotron-narrow.css diff --git a/web/favicon.ico b/src/main/resources/static/favicon.ico similarity index 100% rename from web/favicon.ico rename to src/main/resources/static/favicon.ico diff --git a/web/fonts/glyphicons-halflings-regular.eot b/src/main/resources/static/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from web/fonts/glyphicons-halflings-regular.eot rename to src/main/resources/static/fonts/glyphicons-halflings-regular.eot diff --git a/web/fonts/glyphicons-halflings-regular.svg b/src/main/resources/static/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from web/fonts/glyphicons-halflings-regular.svg rename to src/main/resources/static/fonts/glyphicons-halflings-regular.svg diff --git a/web/fonts/glyphicons-halflings-regular.ttf b/src/main/resources/static/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from web/fonts/glyphicons-halflings-regular.ttf rename to src/main/resources/static/fonts/glyphicons-halflings-regular.ttf diff --git a/web/fonts/glyphicons-halflings-regular.woff b/src/main/resources/static/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from web/fonts/glyphicons-halflings-regular.woff rename to src/main/resources/static/fonts/glyphicons-halflings-regular.woff diff --git a/web/fonts/glyphicons-halflings-regular.woff2 b/src/main/resources/static/fonts/glyphicons-halflings-regular.woff2 similarity index 100% rename from web/fonts/glyphicons-halflings-regular.woff2 rename to src/main/resources/static/fonts/glyphicons-halflings-regular.woff2 diff --git a/web/img/flags/ad.png b/src/main/resources/static/img/flags/ad.png similarity index 100% rename from web/img/flags/ad.png rename to src/main/resources/static/img/flags/ad.png diff --git a/web/img/flags/ae.png b/src/main/resources/static/img/flags/ae.png similarity index 100% rename from web/img/flags/ae.png rename to src/main/resources/static/img/flags/ae.png diff --git a/web/img/flags/af.png b/src/main/resources/static/img/flags/af.png similarity index 100% rename from web/img/flags/af.png rename to src/main/resources/static/img/flags/af.png diff --git a/web/img/flags/ag.png b/src/main/resources/static/img/flags/ag.png similarity index 100% rename from web/img/flags/ag.png rename to src/main/resources/static/img/flags/ag.png diff --git a/web/img/flags/ai.png b/src/main/resources/static/img/flags/ai.png similarity index 100% rename from web/img/flags/ai.png rename to src/main/resources/static/img/flags/ai.png diff --git a/web/img/flags/al.png b/src/main/resources/static/img/flags/al.png similarity index 100% rename from web/img/flags/al.png rename to src/main/resources/static/img/flags/al.png diff --git a/web/img/flags/am.png b/src/main/resources/static/img/flags/am.png similarity index 100% rename from web/img/flags/am.png rename to src/main/resources/static/img/flags/am.png diff --git a/web/img/flags/an.png b/src/main/resources/static/img/flags/an.png similarity index 100% rename from web/img/flags/an.png rename to src/main/resources/static/img/flags/an.png diff --git a/web/img/flags/ao.png b/src/main/resources/static/img/flags/ao.png similarity index 100% rename from web/img/flags/ao.png rename to src/main/resources/static/img/flags/ao.png diff --git a/web/img/flags/ar.png b/src/main/resources/static/img/flags/ar.png similarity index 100% rename from web/img/flags/ar.png rename to src/main/resources/static/img/flags/ar.png diff --git a/web/img/flags/as.png b/src/main/resources/static/img/flags/as.png similarity index 100% rename from web/img/flags/as.png rename to src/main/resources/static/img/flags/as.png diff --git a/web/img/flags/at.png b/src/main/resources/static/img/flags/at.png similarity index 100% rename from web/img/flags/at.png rename to src/main/resources/static/img/flags/at.png diff --git a/web/img/flags/au.png b/src/main/resources/static/img/flags/au.png similarity index 100% rename from web/img/flags/au.png rename to src/main/resources/static/img/flags/au.png diff --git a/web/img/flags/aw.png b/src/main/resources/static/img/flags/aw.png similarity index 100% rename from web/img/flags/aw.png rename to src/main/resources/static/img/flags/aw.png diff --git a/web/img/flags/ax.png b/src/main/resources/static/img/flags/ax.png similarity index 100% rename from web/img/flags/ax.png rename to src/main/resources/static/img/flags/ax.png diff --git a/web/img/flags/az.png b/src/main/resources/static/img/flags/az.png similarity index 100% rename from web/img/flags/az.png rename to src/main/resources/static/img/flags/az.png diff --git a/web/img/flags/ba.png b/src/main/resources/static/img/flags/ba.png similarity index 100% rename from web/img/flags/ba.png rename to src/main/resources/static/img/flags/ba.png diff --git a/web/img/flags/bb.png b/src/main/resources/static/img/flags/bb.png similarity index 100% rename from web/img/flags/bb.png rename to src/main/resources/static/img/flags/bb.png diff --git a/web/img/flags/bd.png b/src/main/resources/static/img/flags/bd.png similarity index 100% rename from web/img/flags/bd.png rename to src/main/resources/static/img/flags/bd.png diff --git a/web/img/flags/be.png b/src/main/resources/static/img/flags/be.png similarity index 100% rename from web/img/flags/be.png rename to src/main/resources/static/img/flags/be.png diff --git a/web/img/flags/bf.png b/src/main/resources/static/img/flags/bf.png similarity index 100% rename from web/img/flags/bf.png rename to src/main/resources/static/img/flags/bf.png diff --git a/web/img/flags/bg.png b/src/main/resources/static/img/flags/bg.png similarity index 100% rename from web/img/flags/bg.png rename to src/main/resources/static/img/flags/bg.png diff --git a/web/img/flags/bh.png b/src/main/resources/static/img/flags/bh.png similarity index 100% rename from web/img/flags/bh.png rename to src/main/resources/static/img/flags/bh.png diff --git a/web/img/flags/bi.png b/src/main/resources/static/img/flags/bi.png similarity index 100% rename from web/img/flags/bi.png rename to src/main/resources/static/img/flags/bi.png diff --git a/web/img/flags/bj.png b/src/main/resources/static/img/flags/bj.png similarity index 100% rename from web/img/flags/bj.png rename to src/main/resources/static/img/flags/bj.png diff --git a/web/img/flags/bm.png b/src/main/resources/static/img/flags/bm.png similarity index 100% rename from web/img/flags/bm.png rename to src/main/resources/static/img/flags/bm.png diff --git a/web/img/flags/bn.png b/src/main/resources/static/img/flags/bn.png similarity index 100% rename from web/img/flags/bn.png rename to src/main/resources/static/img/flags/bn.png diff --git a/web/img/flags/bo.png b/src/main/resources/static/img/flags/bo.png similarity index 100% rename from web/img/flags/bo.png rename to src/main/resources/static/img/flags/bo.png diff --git a/web/img/flags/br.png b/src/main/resources/static/img/flags/br.png similarity index 100% rename from web/img/flags/br.png rename to src/main/resources/static/img/flags/br.png diff --git a/web/img/flags/bs.png b/src/main/resources/static/img/flags/bs.png similarity index 100% rename from web/img/flags/bs.png rename to src/main/resources/static/img/flags/bs.png diff --git a/web/img/flags/bt.png b/src/main/resources/static/img/flags/bt.png similarity index 100% rename from web/img/flags/bt.png rename to src/main/resources/static/img/flags/bt.png diff --git a/web/img/flags/bv.png b/src/main/resources/static/img/flags/bv.png similarity index 100% rename from web/img/flags/bv.png rename to src/main/resources/static/img/flags/bv.png diff --git a/web/img/flags/bw.png b/src/main/resources/static/img/flags/bw.png similarity index 100% rename from web/img/flags/bw.png rename to src/main/resources/static/img/flags/bw.png diff --git a/web/img/flags/by.png b/src/main/resources/static/img/flags/by.png similarity index 100% rename from web/img/flags/by.png rename to src/main/resources/static/img/flags/by.png diff --git a/web/img/flags/bz.png b/src/main/resources/static/img/flags/bz.png similarity index 100% rename from web/img/flags/bz.png rename to src/main/resources/static/img/flags/bz.png diff --git a/web/img/flags/ca.png b/src/main/resources/static/img/flags/ca.png similarity index 100% rename from web/img/flags/ca.png rename to src/main/resources/static/img/flags/ca.png diff --git a/web/img/flags/catalonia.png b/src/main/resources/static/img/flags/catalonia.png similarity index 100% rename from web/img/flags/catalonia.png rename to src/main/resources/static/img/flags/catalonia.png diff --git a/web/img/flags/cc.png b/src/main/resources/static/img/flags/cc.png similarity index 100% rename from web/img/flags/cc.png rename to src/main/resources/static/img/flags/cc.png diff --git a/web/img/flags/cd.png b/src/main/resources/static/img/flags/cd.png similarity index 100% rename from web/img/flags/cd.png rename to src/main/resources/static/img/flags/cd.png diff --git a/web/img/flags/cf.png b/src/main/resources/static/img/flags/cf.png similarity index 100% rename from web/img/flags/cf.png rename to src/main/resources/static/img/flags/cf.png diff --git a/web/img/flags/cg.png b/src/main/resources/static/img/flags/cg.png similarity index 100% rename from web/img/flags/cg.png rename to src/main/resources/static/img/flags/cg.png diff --git a/web/img/flags/ch.png b/src/main/resources/static/img/flags/ch.png similarity index 100% rename from web/img/flags/ch.png rename to src/main/resources/static/img/flags/ch.png diff --git a/web/img/flags/ci.png b/src/main/resources/static/img/flags/ci.png similarity index 100% rename from web/img/flags/ci.png rename to src/main/resources/static/img/flags/ci.png diff --git a/web/img/flags/ck.png b/src/main/resources/static/img/flags/ck.png similarity index 100% rename from web/img/flags/ck.png rename to src/main/resources/static/img/flags/ck.png diff --git a/web/img/flags/cl.png b/src/main/resources/static/img/flags/cl.png similarity index 100% rename from web/img/flags/cl.png rename to src/main/resources/static/img/flags/cl.png diff --git a/web/img/flags/cm.png b/src/main/resources/static/img/flags/cm.png similarity index 100% rename from web/img/flags/cm.png rename to src/main/resources/static/img/flags/cm.png diff --git a/web/img/flags/cn.png b/src/main/resources/static/img/flags/cn.png similarity index 100% rename from web/img/flags/cn.png rename to src/main/resources/static/img/flags/cn.png diff --git a/web/img/flags/co.png b/src/main/resources/static/img/flags/co.png similarity index 100% rename from web/img/flags/co.png rename to src/main/resources/static/img/flags/co.png diff --git a/web/img/flags/cr.png b/src/main/resources/static/img/flags/cr.png similarity index 100% rename from web/img/flags/cr.png rename to src/main/resources/static/img/flags/cr.png diff --git a/web/img/flags/cs.png b/src/main/resources/static/img/flags/cs.png similarity index 100% rename from web/img/flags/cs.png rename to src/main/resources/static/img/flags/cs.png diff --git a/web/img/flags/cu.png b/src/main/resources/static/img/flags/cu.png similarity index 100% rename from web/img/flags/cu.png rename to src/main/resources/static/img/flags/cu.png diff --git a/web/img/flags/cv.png b/src/main/resources/static/img/flags/cv.png similarity index 100% rename from web/img/flags/cv.png rename to src/main/resources/static/img/flags/cv.png diff --git a/web/img/flags/cx.png b/src/main/resources/static/img/flags/cx.png similarity index 100% rename from web/img/flags/cx.png rename to src/main/resources/static/img/flags/cx.png diff --git a/web/img/flags/cy.png b/src/main/resources/static/img/flags/cy.png similarity index 100% rename from web/img/flags/cy.png rename to src/main/resources/static/img/flags/cy.png diff --git a/web/img/flags/cz.png b/src/main/resources/static/img/flags/cz.png similarity index 100% rename from web/img/flags/cz.png rename to src/main/resources/static/img/flags/cz.png diff --git a/web/img/flags/de.png b/src/main/resources/static/img/flags/de.png similarity index 100% rename from web/img/flags/de.png rename to src/main/resources/static/img/flags/de.png diff --git a/web/img/flags/dj.png b/src/main/resources/static/img/flags/dj.png similarity index 100% rename from web/img/flags/dj.png rename to src/main/resources/static/img/flags/dj.png diff --git a/web/img/flags/dk.png b/src/main/resources/static/img/flags/dk.png similarity index 100% rename from web/img/flags/dk.png rename to src/main/resources/static/img/flags/dk.png diff --git a/web/img/flags/dm.png b/src/main/resources/static/img/flags/dm.png similarity index 100% rename from web/img/flags/dm.png rename to src/main/resources/static/img/flags/dm.png diff --git a/web/img/flags/do.png b/src/main/resources/static/img/flags/do.png similarity index 100% rename from web/img/flags/do.png rename to src/main/resources/static/img/flags/do.png diff --git a/web/img/flags/dz.png b/src/main/resources/static/img/flags/dz.png similarity index 100% rename from web/img/flags/dz.png rename to src/main/resources/static/img/flags/dz.png diff --git a/web/img/flags/ec.png b/src/main/resources/static/img/flags/ec.png similarity index 100% rename from web/img/flags/ec.png rename to src/main/resources/static/img/flags/ec.png diff --git a/web/img/flags/ee.png b/src/main/resources/static/img/flags/ee.png similarity index 100% rename from web/img/flags/ee.png rename to src/main/resources/static/img/flags/ee.png diff --git a/web/img/flags/eg.png b/src/main/resources/static/img/flags/eg.png similarity index 100% rename from web/img/flags/eg.png rename to src/main/resources/static/img/flags/eg.png diff --git a/web/img/flags/eh.png b/src/main/resources/static/img/flags/eh.png similarity index 100% rename from web/img/flags/eh.png rename to src/main/resources/static/img/flags/eh.png diff --git a/web/img/flags/england.png b/src/main/resources/static/img/flags/england.png similarity index 100% rename from web/img/flags/england.png rename to src/main/resources/static/img/flags/england.png diff --git a/web/img/flags/er.png b/src/main/resources/static/img/flags/er.png similarity index 100% rename from web/img/flags/er.png rename to src/main/resources/static/img/flags/er.png diff --git a/web/img/flags/es.png b/src/main/resources/static/img/flags/es.png similarity index 100% rename from web/img/flags/es.png rename to src/main/resources/static/img/flags/es.png diff --git a/web/img/flags/et.png b/src/main/resources/static/img/flags/et.png similarity index 100% rename from web/img/flags/et.png rename to src/main/resources/static/img/flags/et.png diff --git a/web/img/flags/europeanunion.png b/src/main/resources/static/img/flags/europeanunion.png similarity index 100% rename from web/img/flags/europeanunion.png rename to src/main/resources/static/img/flags/europeanunion.png diff --git a/web/img/flags/fam.png b/src/main/resources/static/img/flags/fam.png similarity index 100% rename from web/img/flags/fam.png rename to src/main/resources/static/img/flags/fam.png diff --git a/web/img/flags/fi.png b/src/main/resources/static/img/flags/fi.png similarity index 100% rename from web/img/flags/fi.png rename to src/main/resources/static/img/flags/fi.png diff --git a/web/img/flags/fj.png b/src/main/resources/static/img/flags/fj.png similarity index 100% rename from web/img/flags/fj.png rename to src/main/resources/static/img/flags/fj.png diff --git a/web/img/flags/fk.png b/src/main/resources/static/img/flags/fk.png similarity index 100% rename from web/img/flags/fk.png rename to src/main/resources/static/img/flags/fk.png diff --git a/web/img/flags/fm.png b/src/main/resources/static/img/flags/fm.png similarity index 100% rename from web/img/flags/fm.png rename to src/main/resources/static/img/flags/fm.png diff --git a/web/img/flags/fo.png b/src/main/resources/static/img/flags/fo.png similarity index 100% rename from web/img/flags/fo.png rename to src/main/resources/static/img/flags/fo.png diff --git a/web/img/flags/fr.png b/src/main/resources/static/img/flags/fr.png similarity index 100% rename from web/img/flags/fr.png rename to src/main/resources/static/img/flags/fr.png diff --git a/web/img/flags/ga.png b/src/main/resources/static/img/flags/ga.png similarity index 100% rename from web/img/flags/ga.png rename to src/main/resources/static/img/flags/ga.png diff --git a/web/img/flags/gb.png b/src/main/resources/static/img/flags/gb.png similarity index 100% rename from web/img/flags/gb.png rename to src/main/resources/static/img/flags/gb.png diff --git a/web/img/flags/gd.png b/src/main/resources/static/img/flags/gd.png similarity index 100% rename from web/img/flags/gd.png rename to src/main/resources/static/img/flags/gd.png diff --git a/web/img/flags/ge.png b/src/main/resources/static/img/flags/ge.png similarity index 100% rename from web/img/flags/ge.png rename to src/main/resources/static/img/flags/ge.png diff --git a/web/img/flags/gf.png b/src/main/resources/static/img/flags/gf.png similarity index 100% rename from web/img/flags/gf.png rename to src/main/resources/static/img/flags/gf.png diff --git a/web/img/flags/gh.png b/src/main/resources/static/img/flags/gh.png similarity index 100% rename from web/img/flags/gh.png rename to src/main/resources/static/img/flags/gh.png diff --git a/web/img/flags/gi.png b/src/main/resources/static/img/flags/gi.png similarity index 100% rename from web/img/flags/gi.png rename to src/main/resources/static/img/flags/gi.png diff --git a/web/img/flags/gl.png b/src/main/resources/static/img/flags/gl.png similarity index 100% rename from web/img/flags/gl.png rename to src/main/resources/static/img/flags/gl.png diff --git a/web/img/flags/gm.png b/src/main/resources/static/img/flags/gm.png similarity index 100% rename from web/img/flags/gm.png rename to src/main/resources/static/img/flags/gm.png diff --git a/web/img/flags/gn.png b/src/main/resources/static/img/flags/gn.png similarity index 100% rename from web/img/flags/gn.png rename to src/main/resources/static/img/flags/gn.png diff --git a/web/img/flags/gp.png b/src/main/resources/static/img/flags/gp.png similarity index 100% rename from web/img/flags/gp.png rename to src/main/resources/static/img/flags/gp.png diff --git a/web/img/flags/gq.png b/src/main/resources/static/img/flags/gq.png similarity index 100% rename from web/img/flags/gq.png rename to src/main/resources/static/img/flags/gq.png diff --git a/web/img/flags/gr.png b/src/main/resources/static/img/flags/gr.png similarity index 100% rename from web/img/flags/gr.png rename to src/main/resources/static/img/flags/gr.png diff --git a/web/img/flags/gs.png b/src/main/resources/static/img/flags/gs.png similarity index 100% rename from web/img/flags/gs.png rename to src/main/resources/static/img/flags/gs.png diff --git a/web/img/flags/gt.png b/src/main/resources/static/img/flags/gt.png similarity index 100% rename from web/img/flags/gt.png rename to src/main/resources/static/img/flags/gt.png diff --git a/web/img/flags/gu.png b/src/main/resources/static/img/flags/gu.png similarity index 100% rename from web/img/flags/gu.png rename to src/main/resources/static/img/flags/gu.png diff --git a/web/img/flags/gw.png b/src/main/resources/static/img/flags/gw.png similarity index 100% rename from web/img/flags/gw.png rename to src/main/resources/static/img/flags/gw.png diff --git a/web/img/flags/gy.png b/src/main/resources/static/img/flags/gy.png similarity index 100% rename from web/img/flags/gy.png rename to src/main/resources/static/img/flags/gy.png diff --git a/web/img/flags/hk.png b/src/main/resources/static/img/flags/hk.png similarity index 100% rename from web/img/flags/hk.png rename to src/main/resources/static/img/flags/hk.png diff --git a/web/img/flags/hm.png b/src/main/resources/static/img/flags/hm.png similarity index 100% rename from web/img/flags/hm.png rename to src/main/resources/static/img/flags/hm.png diff --git a/web/img/flags/hn.png b/src/main/resources/static/img/flags/hn.png similarity index 100% rename from web/img/flags/hn.png rename to src/main/resources/static/img/flags/hn.png diff --git a/web/img/flags/hr.png b/src/main/resources/static/img/flags/hr.png similarity index 100% rename from web/img/flags/hr.png rename to src/main/resources/static/img/flags/hr.png diff --git a/web/img/flags/ht.png b/src/main/resources/static/img/flags/ht.png similarity index 100% rename from web/img/flags/ht.png rename to src/main/resources/static/img/flags/ht.png diff --git a/web/img/flags/hu.png b/src/main/resources/static/img/flags/hu.png similarity index 100% rename from web/img/flags/hu.png rename to src/main/resources/static/img/flags/hu.png diff --git a/web/img/flags/id.png b/src/main/resources/static/img/flags/id.png similarity index 100% rename from web/img/flags/id.png rename to src/main/resources/static/img/flags/id.png diff --git a/web/img/flags/ie.png b/src/main/resources/static/img/flags/ie.png similarity index 100% rename from web/img/flags/ie.png rename to src/main/resources/static/img/flags/ie.png diff --git a/web/img/flags/il.png b/src/main/resources/static/img/flags/il.png similarity index 100% rename from web/img/flags/il.png rename to src/main/resources/static/img/flags/il.png diff --git a/web/img/flags/in.png b/src/main/resources/static/img/flags/in.png similarity index 100% rename from web/img/flags/in.png rename to src/main/resources/static/img/flags/in.png diff --git a/web/img/flags/io.png b/src/main/resources/static/img/flags/io.png similarity index 100% rename from web/img/flags/io.png rename to src/main/resources/static/img/flags/io.png diff --git a/web/img/flags/iq.png b/src/main/resources/static/img/flags/iq.png similarity index 100% rename from web/img/flags/iq.png rename to src/main/resources/static/img/flags/iq.png diff --git a/web/img/flags/ir.png b/src/main/resources/static/img/flags/ir.png similarity index 100% rename from web/img/flags/ir.png rename to src/main/resources/static/img/flags/ir.png diff --git a/web/img/flags/is.png b/src/main/resources/static/img/flags/is.png similarity index 100% rename from web/img/flags/is.png rename to src/main/resources/static/img/flags/is.png diff --git a/web/img/flags/it.png b/src/main/resources/static/img/flags/it.png similarity index 100% rename from web/img/flags/it.png rename to src/main/resources/static/img/flags/it.png diff --git a/web/img/flags/jm.png b/src/main/resources/static/img/flags/jm.png similarity index 100% rename from web/img/flags/jm.png rename to src/main/resources/static/img/flags/jm.png diff --git a/web/img/flags/jo.png b/src/main/resources/static/img/flags/jo.png similarity index 100% rename from web/img/flags/jo.png rename to src/main/resources/static/img/flags/jo.png diff --git a/web/img/flags/jp.png b/src/main/resources/static/img/flags/jp.png similarity index 100% rename from web/img/flags/jp.png rename to src/main/resources/static/img/flags/jp.png diff --git a/web/img/flags/ke.png b/src/main/resources/static/img/flags/ke.png similarity index 100% rename from web/img/flags/ke.png rename to src/main/resources/static/img/flags/ke.png diff --git a/web/img/flags/kg.png b/src/main/resources/static/img/flags/kg.png similarity index 100% rename from web/img/flags/kg.png rename to src/main/resources/static/img/flags/kg.png diff --git a/web/img/flags/kh.png b/src/main/resources/static/img/flags/kh.png similarity index 100% rename from web/img/flags/kh.png rename to src/main/resources/static/img/flags/kh.png diff --git a/web/img/flags/ki.png b/src/main/resources/static/img/flags/ki.png similarity index 100% rename from web/img/flags/ki.png rename to src/main/resources/static/img/flags/ki.png diff --git a/web/img/flags/km.png b/src/main/resources/static/img/flags/km.png similarity index 100% rename from web/img/flags/km.png rename to src/main/resources/static/img/flags/km.png diff --git a/web/img/flags/kn.png b/src/main/resources/static/img/flags/kn.png similarity index 100% rename from web/img/flags/kn.png rename to src/main/resources/static/img/flags/kn.png diff --git a/web/img/flags/kp.png b/src/main/resources/static/img/flags/kp.png similarity index 100% rename from web/img/flags/kp.png rename to src/main/resources/static/img/flags/kp.png diff --git a/web/img/flags/kr.png b/src/main/resources/static/img/flags/kr.png similarity index 100% rename from web/img/flags/kr.png rename to src/main/resources/static/img/flags/kr.png diff --git a/web/img/flags/kw.png b/src/main/resources/static/img/flags/kw.png similarity index 100% rename from web/img/flags/kw.png rename to src/main/resources/static/img/flags/kw.png diff --git a/web/img/flags/ky.png b/src/main/resources/static/img/flags/ky.png similarity index 100% rename from web/img/flags/ky.png rename to src/main/resources/static/img/flags/ky.png diff --git a/web/img/flags/kz.png b/src/main/resources/static/img/flags/kz.png similarity index 100% rename from web/img/flags/kz.png rename to src/main/resources/static/img/flags/kz.png diff --git a/web/img/flags/la.png b/src/main/resources/static/img/flags/la.png similarity index 100% rename from web/img/flags/la.png rename to src/main/resources/static/img/flags/la.png diff --git a/web/img/flags/lb.png b/src/main/resources/static/img/flags/lb.png similarity index 100% rename from web/img/flags/lb.png rename to src/main/resources/static/img/flags/lb.png diff --git a/web/img/flags/lc.png b/src/main/resources/static/img/flags/lc.png similarity index 100% rename from web/img/flags/lc.png rename to src/main/resources/static/img/flags/lc.png diff --git a/web/img/flags/li.png b/src/main/resources/static/img/flags/li.png similarity index 100% rename from web/img/flags/li.png rename to src/main/resources/static/img/flags/li.png diff --git a/web/img/flags/lk.png b/src/main/resources/static/img/flags/lk.png similarity index 100% rename from web/img/flags/lk.png rename to src/main/resources/static/img/flags/lk.png diff --git a/web/img/flags/lr.png b/src/main/resources/static/img/flags/lr.png similarity index 100% rename from web/img/flags/lr.png rename to src/main/resources/static/img/flags/lr.png diff --git a/web/img/flags/ls.png b/src/main/resources/static/img/flags/ls.png similarity index 100% rename from web/img/flags/ls.png rename to src/main/resources/static/img/flags/ls.png diff --git a/web/img/flags/lt.png b/src/main/resources/static/img/flags/lt.png similarity index 100% rename from web/img/flags/lt.png rename to src/main/resources/static/img/flags/lt.png diff --git a/web/img/flags/lu.png b/src/main/resources/static/img/flags/lu.png similarity index 100% rename from web/img/flags/lu.png rename to src/main/resources/static/img/flags/lu.png diff --git a/web/img/flags/lv.png b/src/main/resources/static/img/flags/lv.png similarity index 100% rename from web/img/flags/lv.png rename to src/main/resources/static/img/flags/lv.png diff --git a/web/img/flags/ly.png b/src/main/resources/static/img/flags/ly.png similarity index 100% rename from web/img/flags/ly.png rename to src/main/resources/static/img/flags/ly.png diff --git a/web/img/flags/ma.png b/src/main/resources/static/img/flags/ma.png similarity index 100% rename from web/img/flags/ma.png rename to src/main/resources/static/img/flags/ma.png diff --git a/web/img/flags/mc.png b/src/main/resources/static/img/flags/mc.png similarity index 100% rename from web/img/flags/mc.png rename to src/main/resources/static/img/flags/mc.png diff --git a/web/img/flags/md.png b/src/main/resources/static/img/flags/md.png similarity index 100% rename from web/img/flags/md.png rename to src/main/resources/static/img/flags/md.png diff --git a/web/img/flags/me.png b/src/main/resources/static/img/flags/me.png similarity index 100% rename from web/img/flags/me.png rename to src/main/resources/static/img/flags/me.png diff --git a/web/img/flags/mg.png b/src/main/resources/static/img/flags/mg.png similarity index 100% rename from web/img/flags/mg.png rename to src/main/resources/static/img/flags/mg.png diff --git a/web/img/flags/mh.png b/src/main/resources/static/img/flags/mh.png similarity index 100% rename from web/img/flags/mh.png rename to src/main/resources/static/img/flags/mh.png diff --git a/web/img/flags/mk.png b/src/main/resources/static/img/flags/mk.png similarity index 100% rename from web/img/flags/mk.png rename to src/main/resources/static/img/flags/mk.png diff --git a/web/img/flags/ml.png b/src/main/resources/static/img/flags/ml.png similarity index 100% rename from web/img/flags/ml.png rename to src/main/resources/static/img/flags/ml.png diff --git a/web/img/flags/mm.png b/src/main/resources/static/img/flags/mm.png similarity index 100% rename from web/img/flags/mm.png rename to src/main/resources/static/img/flags/mm.png diff --git a/web/img/flags/mn.png b/src/main/resources/static/img/flags/mn.png similarity index 100% rename from web/img/flags/mn.png rename to src/main/resources/static/img/flags/mn.png diff --git a/web/img/flags/mo.png b/src/main/resources/static/img/flags/mo.png similarity index 100% rename from web/img/flags/mo.png rename to src/main/resources/static/img/flags/mo.png diff --git a/web/img/flags/mp.png b/src/main/resources/static/img/flags/mp.png similarity index 100% rename from web/img/flags/mp.png rename to src/main/resources/static/img/flags/mp.png diff --git a/web/img/flags/mq.png b/src/main/resources/static/img/flags/mq.png similarity index 100% rename from web/img/flags/mq.png rename to src/main/resources/static/img/flags/mq.png diff --git a/web/img/flags/mr.png b/src/main/resources/static/img/flags/mr.png similarity index 100% rename from web/img/flags/mr.png rename to src/main/resources/static/img/flags/mr.png diff --git a/web/img/flags/ms.png b/src/main/resources/static/img/flags/ms.png similarity index 100% rename from web/img/flags/ms.png rename to src/main/resources/static/img/flags/ms.png diff --git a/web/img/flags/mt.png b/src/main/resources/static/img/flags/mt.png similarity index 100% rename from web/img/flags/mt.png rename to src/main/resources/static/img/flags/mt.png diff --git a/web/img/flags/mu.png b/src/main/resources/static/img/flags/mu.png similarity index 100% rename from web/img/flags/mu.png rename to src/main/resources/static/img/flags/mu.png diff --git a/web/img/flags/mv.png b/src/main/resources/static/img/flags/mv.png similarity index 100% rename from web/img/flags/mv.png rename to src/main/resources/static/img/flags/mv.png diff --git a/web/img/flags/mw.png b/src/main/resources/static/img/flags/mw.png similarity index 100% rename from web/img/flags/mw.png rename to src/main/resources/static/img/flags/mw.png diff --git a/web/img/flags/mx.png b/src/main/resources/static/img/flags/mx.png similarity index 100% rename from web/img/flags/mx.png rename to src/main/resources/static/img/flags/mx.png diff --git a/web/img/flags/my.png b/src/main/resources/static/img/flags/my.png similarity index 100% rename from web/img/flags/my.png rename to src/main/resources/static/img/flags/my.png diff --git a/web/img/flags/mz.png b/src/main/resources/static/img/flags/mz.png similarity index 100% rename from web/img/flags/mz.png rename to src/main/resources/static/img/flags/mz.png diff --git a/web/img/flags/na.png b/src/main/resources/static/img/flags/na.png similarity index 100% rename from web/img/flags/na.png rename to src/main/resources/static/img/flags/na.png diff --git a/web/img/flags/nc.png b/src/main/resources/static/img/flags/nc.png similarity index 100% rename from web/img/flags/nc.png rename to src/main/resources/static/img/flags/nc.png diff --git a/web/img/flags/ne.png b/src/main/resources/static/img/flags/ne.png similarity index 100% rename from web/img/flags/ne.png rename to src/main/resources/static/img/flags/ne.png diff --git a/web/img/flags/nf.png b/src/main/resources/static/img/flags/nf.png similarity index 100% rename from web/img/flags/nf.png rename to src/main/resources/static/img/flags/nf.png diff --git a/web/img/flags/ng.png b/src/main/resources/static/img/flags/ng.png similarity index 100% rename from web/img/flags/ng.png rename to src/main/resources/static/img/flags/ng.png diff --git a/web/img/flags/ni.png b/src/main/resources/static/img/flags/ni.png similarity index 100% rename from web/img/flags/ni.png rename to src/main/resources/static/img/flags/ni.png diff --git a/web/img/flags/nl.png b/src/main/resources/static/img/flags/nl.png similarity index 100% rename from web/img/flags/nl.png rename to src/main/resources/static/img/flags/nl.png diff --git a/web/img/flags/no.png b/src/main/resources/static/img/flags/no.png similarity index 100% rename from web/img/flags/no.png rename to src/main/resources/static/img/flags/no.png diff --git a/web/img/flags/np.png b/src/main/resources/static/img/flags/np.png similarity index 100% rename from web/img/flags/np.png rename to src/main/resources/static/img/flags/np.png diff --git a/web/img/flags/nr.png b/src/main/resources/static/img/flags/nr.png similarity index 100% rename from web/img/flags/nr.png rename to src/main/resources/static/img/flags/nr.png diff --git a/web/img/flags/nu.png b/src/main/resources/static/img/flags/nu.png similarity index 100% rename from web/img/flags/nu.png rename to src/main/resources/static/img/flags/nu.png diff --git a/web/img/flags/nz.png b/src/main/resources/static/img/flags/nz.png similarity index 100% rename from web/img/flags/nz.png rename to src/main/resources/static/img/flags/nz.png diff --git a/web/img/flags/om.png b/src/main/resources/static/img/flags/om.png similarity index 100% rename from web/img/flags/om.png rename to src/main/resources/static/img/flags/om.png diff --git a/web/img/flags/pa.png b/src/main/resources/static/img/flags/pa.png similarity index 100% rename from web/img/flags/pa.png rename to src/main/resources/static/img/flags/pa.png diff --git a/web/img/flags/pe.png b/src/main/resources/static/img/flags/pe.png similarity index 100% rename from web/img/flags/pe.png rename to src/main/resources/static/img/flags/pe.png diff --git a/web/img/flags/pf.png b/src/main/resources/static/img/flags/pf.png similarity index 100% rename from web/img/flags/pf.png rename to src/main/resources/static/img/flags/pf.png diff --git a/web/img/flags/pg.png b/src/main/resources/static/img/flags/pg.png similarity index 100% rename from web/img/flags/pg.png rename to src/main/resources/static/img/flags/pg.png diff --git a/web/img/flags/ph.png b/src/main/resources/static/img/flags/ph.png similarity index 100% rename from web/img/flags/ph.png rename to src/main/resources/static/img/flags/ph.png diff --git a/web/img/flags/pk.png b/src/main/resources/static/img/flags/pk.png similarity index 100% rename from web/img/flags/pk.png rename to src/main/resources/static/img/flags/pk.png diff --git a/web/img/flags/pl.png b/src/main/resources/static/img/flags/pl.png similarity index 100% rename from web/img/flags/pl.png rename to src/main/resources/static/img/flags/pl.png diff --git a/web/img/flags/pm.png b/src/main/resources/static/img/flags/pm.png similarity index 100% rename from web/img/flags/pm.png rename to src/main/resources/static/img/flags/pm.png diff --git a/web/img/flags/pn.png b/src/main/resources/static/img/flags/pn.png similarity index 100% rename from web/img/flags/pn.png rename to src/main/resources/static/img/flags/pn.png diff --git a/web/img/flags/pr.png b/src/main/resources/static/img/flags/pr.png similarity index 100% rename from web/img/flags/pr.png rename to src/main/resources/static/img/flags/pr.png diff --git a/web/img/flags/ps.png b/src/main/resources/static/img/flags/ps.png similarity index 100% rename from web/img/flags/ps.png rename to src/main/resources/static/img/flags/ps.png diff --git a/web/img/flags/pt.png b/src/main/resources/static/img/flags/pt.png similarity index 100% rename from web/img/flags/pt.png rename to src/main/resources/static/img/flags/pt.png diff --git a/web/img/flags/pw.png b/src/main/resources/static/img/flags/pw.png similarity index 100% rename from web/img/flags/pw.png rename to src/main/resources/static/img/flags/pw.png diff --git a/web/img/flags/py.png b/src/main/resources/static/img/flags/py.png similarity index 100% rename from web/img/flags/py.png rename to src/main/resources/static/img/flags/py.png diff --git a/web/img/flags/qa.png b/src/main/resources/static/img/flags/qa.png similarity index 100% rename from web/img/flags/qa.png rename to src/main/resources/static/img/flags/qa.png diff --git a/web/img/flags/re.png b/src/main/resources/static/img/flags/re.png similarity index 100% rename from web/img/flags/re.png rename to src/main/resources/static/img/flags/re.png diff --git a/web/img/flags/ro.png b/src/main/resources/static/img/flags/ro.png similarity index 100% rename from web/img/flags/ro.png rename to src/main/resources/static/img/flags/ro.png diff --git a/web/img/flags/rs.png b/src/main/resources/static/img/flags/rs.png similarity index 100% rename from web/img/flags/rs.png rename to src/main/resources/static/img/flags/rs.png diff --git a/web/img/flags/ru.png b/src/main/resources/static/img/flags/ru.png similarity index 100% rename from web/img/flags/ru.png rename to src/main/resources/static/img/flags/ru.png diff --git a/web/img/flags/rw.png b/src/main/resources/static/img/flags/rw.png similarity index 100% rename from web/img/flags/rw.png rename to src/main/resources/static/img/flags/rw.png diff --git a/web/img/flags/sa.png b/src/main/resources/static/img/flags/sa.png similarity index 100% rename from web/img/flags/sa.png rename to src/main/resources/static/img/flags/sa.png diff --git a/web/img/flags/sb.png b/src/main/resources/static/img/flags/sb.png similarity index 100% rename from web/img/flags/sb.png rename to src/main/resources/static/img/flags/sb.png diff --git a/web/img/flags/sc.png b/src/main/resources/static/img/flags/sc.png similarity index 100% rename from web/img/flags/sc.png rename to src/main/resources/static/img/flags/sc.png diff --git a/web/img/flags/scotland.png b/src/main/resources/static/img/flags/scotland.png similarity index 100% rename from web/img/flags/scotland.png rename to src/main/resources/static/img/flags/scotland.png diff --git a/web/img/flags/sd.png b/src/main/resources/static/img/flags/sd.png similarity index 100% rename from web/img/flags/sd.png rename to src/main/resources/static/img/flags/sd.png diff --git a/web/img/flags/se.png b/src/main/resources/static/img/flags/se.png similarity index 100% rename from web/img/flags/se.png rename to src/main/resources/static/img/flags/se.png diff --git a/web/img/flags/sg.png b/src/main/resources/static/img/flags/sg.png similarity index 100% rename from web/img/flags/sg.png rename to src/main/resources/static/img/flags/sg.png diff --git a/web/img/flags/sh.png b/src/main/resources/static/img/flags/sh.png similarity index 100% rename from web/img/flags/sh.png rename to src/main/resources/static/img/flags/sh.png diff --git a/web/img/flags/si.png b/src/main/resources/static/img/flags/si.png similarity index 100% rename from web/img/flags/si.png rename to src/main/resources/static/img/flags/si.png diff --git a/web/img/flags/sj.png b/src/main/resources/static/img/flags/sj.png similarity index 100% rename from web/img/flags/sj.png rename to src/main/resources/static/img/flags/sj.png diff --git a/web/img/flags/sk.png b/src/main/resources/static/img/flags/sk.png similarity index 100% rename from web/img/flags/sk.png rename to src/main/resources/static/img/flags/sk.png diff --git a/web/img/flags/sl.png b/src/main/resources/static/img/flags/sl.png similarity index 100% rename from web/img/flags/sl.png rename to src/main/resources/static/img/flags/sl.png diff --git a/web/img/flags/sm.png b/src/main/resources/static/img/flags/sm.png similarity index 100% rename from web/img/flags/sm.png rename to src/main/resources/static/img/flags/sm.png diff --git a/web/img/flags/sn.png b/src/main/resources/static/img/flags/sn.png similarity index 100% rename from web/img/flags/sn.png rename to src/main/resources/static/img/flags/sn.png diff --git a/web/img/flags/so.png b/src/main/resources/static/img/flags/so.png similarity index 100% rename from web/img/flags/so.png rename to src/main/resources/static/img/flags/so.png diff --git a/web/img/flags/sr.png b/src/main/resources/static/img/flags/sr.png similarity index 100% rename from web/img/flags/sr.png rename to src/main/resources/static/img/flags/sr.png diff --git a/web/img/flags/st.png b/src/main/resources/static/img/flags/st.png similarity index 100% rename from web/img/flags/st.png rename to src/main/resources/static/img/flags/st.png diff --git a/web/img/flags/sv.png b/src/main/resources/static/img/flags/sv.png similarity index 100% rename from web/img/flags/sv.png rename to src/main/resources/static/img/flags/sv.png diff --git a/web/img/flags/sy.png b/src/main/resources/static/img/flags/sy.png similarity index 100% rename from web/img/flags/sy.png rename to src/main/resources/static/img/flags/sy.png diff --git a/web/img/flags/sz.png b/src/main/resources/static/img/flags/sz.png similarity index 100% rename from web/img/flags/sz.png rename to src/main/resources/static/img/flags/sz.png diff --git a/web/img/flags/tc.png b/src/main/resources/static/img/flags/tc.png similarity index 100% rename from web/img/flags/tc.png rename to src/main/resources/static/img/flags/tc.png diff --git a/web/img/flags/td.png b/src/main/resources/static/img/flags/td.png similarity index 100% rename from web/img/flags/td.png rename to src/main/resources/static/img/flags/td.png diff --git a/web/img/flags/tf.png b/src/main/resources/static/img/flags/tf.png similarity index 100% rename from web/img/flags/tf.png rename to src/main/resources/static/img/flags/tf.png diff --git a/web/img/flags/tg.png b/src/main/resources/static/img/flags/tg.png similarity index 100% rename from web/img/flags/tg.png rename to src/main/resources/static/img/flags/tg.png diff --git a/web/img/flags/th.png b/src/main/resources/static/img/flags/th.png similarity index 100% rename from web/img/flags/th.png rename to src/main/resources/static/img/flags/th.png diff --git a/web/img/flags/tj.png b/src/main/resources/static/img/flags/tj.png similarity index 100% rename from web/img/flags/tj.png rename to src/main/resources/static/img/flags/tj.png diff --git a/web/img/flags/tk.png b/src/main/resources/static/img/flags/tk.png similarity index 100% rename from web/img/flags/tk.png rename to src/main/resources/static/img/flags/tk.png diff --git a/web/img/flags/tl.png b/src/main/resources/static/img/flags/tl.png similarity index 100% rename from web/img/flags/tl.png rename to src/main/resources/static/img/flags/tl.png diff --git a/web/img/flags/tm.png b/src/main/resources/static/img/flags/tm.png similarity index 100% rename from web/img/flags/tm.png rename to src/main/resources/static/img/flags/tm.png diff --git a/web/img/flags/tn.png b/src/main/resources/static/img/flags/tn.png similarity index 100% rename from web/img/flags/tn.png rename to src/main/resources/static/img/flags/tn.png diff --git a/web/img/flags/to.png b/src/main/resources/static/img/flags/to.png similarity index 100% rename from web/img/flags/to.png rename to src/main/resources/static/img/flags/to.png diff --git a/web/img/flags/tr.png b/src/main/resources/static/img/flags/tr.png similarity index 100% rename from web/img/flags/tr.png rename to src/main/resources/static/img/flags/tr.png diff --git a/web/img/flags/tt.png b/src/main/resources/static/img/flags/tt.png similarity index 100% rename from web/img/flags/tt.png rename to src/main/resources/static/img/flags/tt.png diff --git a/web/img/flags/tv.png b/src/main/resources/static/img/flags/tv.png similarity index 100% rename from web/img/flags/tv.png rename to src/main/resources/static/img/flags/tv.png diff --git a/web/img/flags/tw.png b/src/main/resources/static/img/flags/tw.png similarity index 100% rename from web/img/flags/tw.png rename to src/main/resources/static/img/flags/tw.png diff --git a/web/img/flags/tz.png b/src/main/resources/static/img/flags/tz.png similarity index 100% rename from web/img/flags/tz.png rename to src/main/resources/static/img/flags/tz.png diff --git a/web/img/flags/ua.png b/src/main/resources/static/img/flags/ua.png similarity index 100% rename from web/img/flags/ua.png rename to src/main/resources/static/img/flags/ua.png diff --git a/web/img/flags/ug.png b/src/main/resources/static/img/flags/ug.png similarity index 100% rename from web/img/flags/ug.png rename to src/main/resources/static/img/flags/ug.png diff --git a/web/img/flags/um.png b/src/main/resources/static/img/flags/um.png similarity index 100% rename from web/img/flags/um.png rename to src/main/resources/static/img/flags/um.png diff --git a/web/img/flags/us.png b/src/main/resources/static/img/flags/us.png similarity index 100% rename from web/img/flags/us.png rename to src/main/resources/static/img/flags/us.png diff --git a/web/img/flags/uy.png b/src/main/resources/static/img/flags/uy.png similarity index 100% rename from web/img/flags/uy.png rename to src/main/resources/static/img/flags/uy.png diff --git a/web/img/flags/uz.png b/src/main/resources/static/img/flags/uz.png similarity index 100% rename from web/img/flags/uz.png rename to src/main/resources/static/img/flags/uz.png diff --git a/web/img/flags/va.png b/src/main/resources/static/img/flags/va.png similarity index 100% rename from web/img/flags/va.png rename to src/main/resources/static/img/flags/va.png diff --git a/web/img/flags/vc.png b/src/main/resources/static/img/flags/vc.png similarity index 100% rename from web/img/flags/vc.png rename to src/main/resources/static/img/flags/vc.png diff --git a/web/img/flags/ve.png b/src/main/resources/static/img/flags/ve.png similarity index 100% rename from web/img/flags/ve.png rename to src/main/resources/static/img/flags/ve.png diff --git a/web/img/flags/vg.png b/src/main/resources/static/img/flags/vg.png similarity index 100% rename from web/img/flags/vg.png rename to src/main/resources/static/img/flags/vg.png diff --git a/web/img/flags/vi.png b/src/main/resources/static/img/flags/vi.png similarity index 100% rename from web/img/flags/vi.png rename to src/main/resources/static/img/flags/vi.png diff --git a/web/img/flags/vn.png b/src/main/resources/static/img/flags/vn.png similarity index 100% rename from web/img/flags/vn.png rename to src/main/resources/static/img/flags/vn.png diff --git a/web/img/flags/vu.png b/src/main/resources/static/img/flags/vu.png similarity index 100% rename from web/img/flags/vu.png rename to src/main/resources/static/img/flags/vu.png diff --git a/web/img/flags/wales.png b/src/main/resources/static/img/flags/wales.png similarity index 100% rename from web/img/flags/wales.png rename to src/main/resources/static/img/flags/wales.png diff --git a/web/img/flags/wf.png b/src/main/resources/static/img/flags/wf.png similarity index 100% rename from web/img/flags/wf.png rename to src/main/resources/static/img/flags/wf.png diff --git a/web/img/flags/ws.png b/src/main/resources/static/img/flags/ws.png similarity index 100% rename from web/img/flags/ws.png rename to src/main/resources/static/img/flags/ws.png diff --git a/web/img/flags/ye.png b/src/main/resources/static/img/flags/ye.png similarity index 100% rename from web/img/flags/ye.png rename to src/main/resources/static/img/flags/ye.png diff --git a/web/img/flags/yt.png b/src/main/resources/static/img/flags/yt.png similarity index 100% rename from web/img/flags/yt.png rename to src/main/resources/static/img/flags/yt.png diff --git a/web/img/flags/za.png b/src/main/resources/static/img/flags/za.png similarity index 100% rename from web/img/flags/za.png rename to src/main/resources/static/img/flags/za.png diff --git a/web/img/flags/zm.png b/src/main/resources/static/img/flags/zm.png similarity index 100% rename from web/img/flags/zm.png rename to src/main/resources/static/img/flags/zm.png diff --git a/web/img/flags/zw.png b/src/main/resources/static/img/flags/zw.png similarity index 100% rename from web/img/flags/zw.png rename to src/main/resources/static/img/flags/zw.png diff --git a/web/img/gooey_sweet_32.png b/src/main/resources/static/img/gooey_sweet_32.png similarity index 100% rename from web/img/gooey_sweet_32.png rename to src/main/resources/static/img/gooey_sweet_32.png diff --git a/web/img/sweet-gooey-smallish.png b/src/main/resources/static/img/sweet-gooey-smallish.png similarity index 100% rename from web/img/sweet-gooey-smallish.png rename to src/main/resources/static/img/sweet-gooey-smallish.png diff --git a/web/index.html b/src/main/resources/static/index.html similarity index 100% rename from web/index.html rename to src/main/resources/static/index.html diff --git a/templates/about.ftl b/src/main/resources/views/about.ftl similarity index 100% rename from templates/about.ftl rename to src/main/resources/views/about.ftl diff --git a/templates/add.ftl b/src/main/resources/views/add.ftl similarity index 100% rename from templates/add.ftl rename to src/main/resources/views/add.ftl diff --git a/templates/edit-server-controls.ftl b/src/main/resources/views/edit-server-controls.ftl similarity index 100% rename from templates/edit-server-controls.ftl rename to src/main/resources/views/edit-server-controls.ftl diff --git a/templates/edit.ftl b/src/main/resources/views/edit.ftl similarity index 100% rename from templates/edit.ftl rename to src/main/resources/views/edit.ftl diff --git a/templates/footer.ftl b/src/main/resources/views/footer.ftl similarity index 100% rename from templates/footer.ftl rename to src/main/resources/views/footer.ftl diff --git a/templates/metainfo.ftl b/src/main/resources/views/metainfo.ftl similarity index 100% rename from templates/metainfo.ftl rename to src/main/resources/views/metainfo.ftl diff --git a/templates/module-info.ftl b/src/main/resources/views/module-info.ftl similarity index 100% rename from templates/module-info.ftl rename to src/main/resources/views/module-info.ftl diff --git a/templates/module-list.ftl b/src/main/resources/views/module-list.ftl similarity index 100% rename from templates/module-list.ftl rename to src/main/resources/views/module-list.ftl diff --git a/templates/navigation.ftl b/src/main/resources/views/navigation.ftl similarity index 100% rename from templates/navigation.ftl rename to src/main/resources/views/navigation.ftl diff --git a/templates/server-list.ftl b/src/main/resources/views/server-list.ftl similarity index 100% rename from templates/server-list.ftl rename to src/main/resources/views/server-list.ftl diff --git a/src/test/java/org/terasology/master/WebServerBasedTests.java b/src/test/java/org/terasology/master/WebServerBasedTests.java index 553e389..71edc4d 100644 --- a/src/test/java/org/terasology/master/WebServerBasedTests.java +++ b/src/test/java/org/terasology/master/WebServerBasedTests.java @@ -16,12 +16,6 @@ package org.terasology.master; -import java.io.File; -import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.util.concurrent.atomic.AtomicInteger; - import org.eclipse.jetty.server.Server; import org.h2.jdbcx.JdbcDataSource; import org.junit.AfterClass; @@ -38,10 +32,15 @@ import org.terasology.web.model.ServerEntry; import org.terasology.web.model.ServerListModel; import org.terasology.web.model.ServerListModelImpl; -import org.terasology.web.servlet.AboutServlet; -import org.terasology.web.servlet.ModuleServlet; +import org.terasology.web.servlet.AboutController; import org.terasology.web.servlet.ServerServlet; +import java.io.File; +import java.io.IOException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.concurrent.atomic.AtomicInteger; + public abstract class WebServerBasedTests { @ClassRule @@ -95,9 +94,9 @@ public static void setup() throws Exception { ServerListModel serverListModel = new ServerListModelImpl(dataBase, SERVER_TABLE, secret); webServer = JettyMain.createServer(PORT, - new AboutServlet(), - new ServerServlet(serverListModel), // the server list servlet - new ModuleServlet(moduleListModel)); // the module list servlet + new AboutController(), + new ServerServlet(serverListModel)); // the server list servlet +// new ModuleServlet(moduleListModel)); // the module list servlet webServer.start(); From 99a6d2373f1b34d9a60a273121d48d1cbe6df3e0 Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 12:31:42 +0300 Subject: [PATCH 02/20] migration(micronauts): fix tests --- build.gradle | 7 +- .../java/org/terasology/web/JettyMain.java | 31 ++-- .../org/terasology/web/db/JooqDatabase.java | 33 ++-- .../web/geo/dbip/GeoLocationServiceDbIp.java | 9 +- .../web/model/ModuleListModelImpl.java | 8 +- .../web/model/ServerListModelImpl.java | 18 ++- .../terasology/web/model/ZipExtractor.java | 14 +- src/main/resources/application-test.yml | 6 + src/main/resources/application.yml | 10 +- .../java/org/terasology/master/BaseTests.java | 63 ++++++++ .../org/terasology/master/JooqDbTest.java | 39 ++--- .../terasology/master/ModuleJsonListTest.java | 148 +++++++++--------- .../org/terasology/master/ModuleShowTest.java | 80 +++++----- .../terasology/master/ModuleUpdateTest.java | 84 +++++----- .../master/ServerHtmlContentTest.java | 22 ++- .../terasology/master/ServerJsonListTest.java | 42 ++--- .../org/terasology/master/ValidatorTests.java | 108 +++++-------- .../master/WebServerBasedTests.java | 128 --------------- .../{ => services}/DummyArtifactRepo.java | 12 +- .../master/{ => services}/DummyExtractor.java | 17 +- .../DummyGeoLocationService.java | 9 +- 21 files changed, 407 insertions(+), 481 deletions(-) create mode 100644 src/main/resources/application-test.yml create mode 100644 src/test/java/org/terasology/master/BaseTests.java delete mode 100644 src/test/java/org/terasology/master/WebServerBasedTests.java rename src/test/java/org/terasology/master/{ => services}/DummyArtifactRepo.java (91%) rename src/test/java/org/terasology/master/{ => services}/DummyExtractor.java (88%) rename src/test/java/org/terasology/master/{ => services}/DummyGeoLocationService.java (91%) diff --git a/build.gradle b/build.gradle index 9e12a9d..4e1e7fa 100644 --- a/build.gradle +++ b/build.gradle @@ -67,11 +67,12 @@ dependencies { testAnnotationProcessor("io.micronaut:micronaut-inject-java") testImplementation(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")) testImplementation("org.junit.jupiter:junit-jupiter-api") + testImplementation("org.junit.jupiter:junit-jupiter-params") testImplementation("io.micronaut.test:micronaut-test-junit5") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") - testImplementation(platform("org.testcontainers:testcontainers-bom:1.14.3")) - testRuntimeOnly("org.testcontainers:postgresql") +// testImplementation(platform("org.testcontainers:testcontainers-bom:1.14.3")) +// testRuntimeOnly("org.testcontainers:postgresql") /* Micronauts end*/ implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: jettyVersion @@ -100,7 +101,7 @@ dependencies { testImplementation 'com.jcabi:jcabi-w3c:1.3' testImplementation 'com.jcabi:jcabi-matchers:1.4' testImplementation 'junit:junit:4.12' - testImplementation 'com.h2database:h2:1.4.190' + testImplementation("com.h2database:h2") testImplementation 'org.slf4j:slf4j-api:1.7.30' runtimeOnly group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.3' diff --git a/src/main/java/org/terasology/web/JettyMain.java b/src/main/java/org/terasology/web/JettyMain.java index 695a246..4944baf 100644 --- a/src/main/java/org/terasology/web/JettyMain.java +++ b/src/main/java/org/terasology/web/JettyMain.java @@ -30,20 +30,16 @@ import org.glassfish.jersey.servlet.ServletContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.web.artifactory.ArtifactoryRepo; import org.terasology.web.db.DataBase; import org.terasology.web.db.JooqDatabase; import org.terasology.web.geo.GeoLocationService; import org.terasology.web.geo.dbip.GeoLocationServiceDbIp; import org.terasology.web.io.GsonMessageBodyHandler; -import org.terasology.web.model.ModuleListModelImpl; import org.terasology.web.model.ServerListModel; import org.terasology.web.model.ServerListModelImpl; import javax.servlet.DispatcherType; import java.net.URI; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.EnumSet; import java.util.Locale; @@ -98,19 +94,18 @@ public static void main(String[] args) throws Exception { String snapshotRepo = "terasology-snapshot-local"; String modGroup = "org.terasology.modules"; String engineGroup = "org.terasology.engine"; - Path cacheFolder = Paths.get("cache", "modules"); - - ModuleListModelImpl moduleListModel = new ModuleListModelImpl(cacheFolder); - Path releaseRepoFolder = cacheFolder.resolve(releaseRepo); - Path snapshotRepoFolder = cacheFolder.resolve(snapshotRepo); - - // add module repos - moduleListModel.addRepository(ArtifactoryRepo.release(host, releaseRepo, modGroup, releaseRepoFolder)); - moduleListModel.addRepository(ArtifactoryRepo.snapshot(host, snapshotRepo, modGroup, snapshotRepoFolder)); - - // add engine repos - moduleListModel.addRepository(ArtifactoryRepo.release(host, releaseRepo, engineGroup, releaseRepoFolder)); - moduleListModel.addRepository(ArtifactoryRepo.snapshot(host, snapshotRepo, engineGroup, snapshotRepoFolder)); +// +// ModuleListModelImpl moduleListModel = new ModuleListModelImpl(cacheFolder); +// Path releaseRepoFolder = cacheFolder.resolve(releaseRepo); +// Path snapshotRepoFolder = cacheFolder.resolve(snapshotRepo); +// +// // add module repos +// moduleListModel.addRepository(ArtifactoryRepo.release(host, releaseRepo, modGroup, releaseRepoFolder)); +// moduleListModel.addRepository(ArtifactoryRepo.snapshot(host, snapshotRepo, modGroup, snapshotRepoFolder)); +// +// // add engine repos +// moduleListModel.addRepository(ArtifactoryRepo.release(host, releaseRepo, engineGroup, releaseRepoFolder)); +// moduleListModel.addRepository(ArtifactoryRepo.snapshot(host, snapshotRepo, engineGroup, snapshotRepoFolder)); HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:postgresql://" + dbUri.getHost() + ":" + dbPort + dbUri.getPath()); @@ -134,7 +129,7 @@ public static void main(String[] args) throws Exception { logger.info("Server started on port {}!", port); - new Thread(moduleListModel::updateAllModules).start(); +// new Thread(moduleListModel::updateAllModules).start(); // server.join(); } diff --git a/src/main/java/org/terasology/web/db/JooqDatabase.java b/src/main/java/org/terasology/web/db/JooqDatabase.java index 1f32328..b2b42a7 100644 --- a/src/main/java/org/terasology/web/db/JooqDatabase.java +++ b/src/main/java/org/terasology/web/db/JooqDatabase.java @@ -16,28 +16,8 @@ package org.terasology.web.db; -import java.io.IOException; -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.sql.DataSource; - -import org.jooq.DSLContext; -import org.jooq.Field; -import org.jooq.InsertSetMoreStep; -import org.jooq.Query; import org.jooq.Record; -import org.jooq.Result; -import org.jooq.SortField; -import org.jooq.Table; -import org.jooq.UpdateSetMoreStep; +import org.jooq.*; import org.jooq.impl.DSL; import org.jooq.impl.SQLDataType; import org.slf4j.Logger; @@ -45,8 +25,19 @@ import org.terasology.web.geo.GeoLocation; import org.terasology.web.geo.GeoLocationService; +import javax.inject.Singleton; +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.*; +import java.util.Map.Entry; + /** + * */ +@Singleton public final class JooqDatabase implements DataBase { private static final Logger logger = LoggerFactory.getLogger(JooqDatabase.class); diff --git a/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java b/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java index bdf6a5a..0897e16 100644 --- a/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java +++ b/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java @@ -16,18 +16,19 @@ package org.terasology.web.geo.dbip; -import java.io.IOException; -import java.net.InetAddress; - import org.terasology.web.geo.GeoLocation; import org.terasology.web.geo.GeoLocationService; - import retrofit.RestAdapter; +import javax.inject.Singleton; +import java.io.IOException; +import java.net.InetAddress; + /** * Resolves geo-location for a hostname or IP address based on db-ip.com. * Requires a system environment variable "DBIP_API_KEY" with a valid API key. */ +@Singleton public class GeoLocationServiceDbIp implements GeoLocationService { private final String apiKey; diff --git a/src/main/java/org/terasology/web/model/ModuleListModelImpl.java b/src/main/java/org/terasology/web/model/ModuleListModelImpl.java index f9eaff1..ebf140e 100644 --- a/src/main/java/org/terasology/web/model/ModuleListModelImpl.java +++ b/src/main/java/org/terasology/web/model/ModuleListModelImpl.java @@ -60,11 +60,9 @@ public class ModuleListModelImpl implements ModuleListModel { private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); - public ModuleListModelImpl(@Value("${meta-server.cacheFolder}") Path cacheFolder) { - this(cacheFolder, new ZipExtractor("module.txt", "engine-module.txt")); - } - - public ModuleListModelImpl(Path cacheFolder, MetadataExtractor extractor) { + public ModuleListModelImpl( + @Value("${meta-server.cacheFolder}") Path cacheFolder, + MetadataExtractor extractor) { this.cacheFolder = cacheFolder; this.cacheFolder.toFile().mkdirs(); this.extractor = extractor; diff --git a/src/main/java/org/terasology/web/model/ServerListModelImpl.java b/src/main/java/org/terasology/web/model/ServerListModelImpl.java index e675b01..b2b9b55 100644 --- a/src/main/java/org/terasology/web/model/ServerListModelImpl.java +++ b/src/main/java/org/terasology/web/model/ServerListModelImpl.java @@ -16,6 +16,13 @@ package org.terasology.web.model; +import com.google.common.base.Preconditions; +import io.micronaut.context.annotation.Value; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.terasology.web.db.DataBase; + +import javax.inject.Singleton; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; @@ -24,12 +31,7 @@ import java.util.List; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.terasology.web.db.DataBase; - -import com.google.common.base.Preconditions; - +@Singleton public class ServerListModelImpl implements ServerListModel { private static final Logger logger = LoggerFactory.getLogger(ServerListModelImpl.class); @@ -38,7 +40,9 @@ public class ServerListModelImpl implements ServerListModel { private final String tableName; private final String editSecret; - public ServerListModelImpl(DataBase dataBase, String tableName, String editSecret) throws SQLException { + public ServerListModelImpl(DataBase dataBase, + @Value("${meta-server.tableName}") String tableName, + @Value("${meta-server.editSecret}") String editSecret) throws SQLException { Preconditions.checkArgument(dataBase != null, "dataSource must not be null"); Preconditions.checkArgument(tableName != null, "tableName must not be null"); Preconditions.checkArgument(editSecret != null, "editSecret must not be null"); diff --git a/src/main/java/org/terasology/web/model/ZipExtractor.java b/src/main/java/org/terasology/web/model/ZipExtractor.java index 29f9223..b6cc1da 100644 --- a/src/main/java/org/terasology/web/model/ZipExtractor.java +++ b/src/main/java/org/terasology/web/model/ZipExtractor.java @@ -16,11 +16,11 @@ package org.terasology.web.model; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; +import org.terasology.module.ModuleMetadata; +import org.terasology.module.ModuleMetadataJsonAdapter; + +import javax.inject.Singleton; +import java.io.*; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -28,13 +28,11 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; -import org.terasology.module.ModuleMetadata; -import org.terasology.module.ModuleMetadataJsonAdapter; - /** * Extracts the module info file from a ZIP archive that is described by an URL. * The stream is closed as soon as the file has been read. */ +@Singleton public class ZipExtractor implements MetadataExtractor { private final List filename; diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml new file mode 100644 index 0000000..3446f47 --- /dev/null +++ b/src/main/resources/application-test.yml @@ -0,0 +1,6 @@ +datasources: + default: + url: jdbc:h2:mem:testdb + driverClassName: org.h2.Driver + username: sa + password: password \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ce22177..90abaf9 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,6 +6,14 @@ micronaut: base: paths: - "classpath:static" - - +datasources: + default: + url: jdbc:postgresql://localhost:5432/postgres + driverClassName: org.postgresql.Driver + username: postgres + password: '' + meta-server: cacheFolder: "./cache" + tableName: "servers" + editSecret: "foobar" diff --git a/src/test/java/org/terasology/master/BaseTests.java b/src/test/java/org/terasology/master/BaseTests.java new file mode 100644 index 0000000..198f4fd --- /dev/null +++ b/src/test/java/org/terasology/master/BaseTests.java @@ -0,0 +1,63 @@ +package org.terasology.master; + +import io.micronaut.test.annotation.MicronautTest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.terasology.master.services.DummyArtifactRepo; +import org.terasology.web.artifactory.ArtifactRepository; +import org.terasology.web.db.DataBase; +import org.terasology.web.geo.GeoLocation; +import org.terasology.web.geo.GeoLocationService; +import org.terasology.web.model.ModuleListModelImpl; +import org.terasology.web.model.ServerEntry; + +import javax.inject.Inject; +import java.io.IOException; +import java.sql.SQLException; + +@MicronautTest +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class BaseTests { + + private static final String SERVER_TABLE = "servers"; + protected ServerEntry firstEntry; + @Inject + ModuleListModelImpl moduleListModel; + @Inject + DataBase dataBase; + @Inject + GeoLocationService geoService; + + protected DummyArtifactRepo snapshotRepo; + + @BeforeAll + void setupModules() throws IOException, SQLException { + DummyArtifactRepo releaseRepo = new DummyArtifactRepo(ArtifactRepository.RepoType.RELEASE); + try { + releaseRepo.addArtifact("Core", new ClasspathArtifactInfo("/metas/" + "Core-0.53.1.jar_info.json")); + + snapshotRepo = new DummyArtifactRepo(ArtifactRepository.RepoType.SNAPSHOT); + snapshotRepo.addArtifact("ChrisVolume1OST", new ClasspathArtifactInfo("/metas/" + "ChrisVolume1OST-0.2.1-20150608.034649-1.jar_info.json")); + snapshotRepo.addArtifact("MusicDirector", new ClasspathArtifactInfo("/metas/" + "MusicDirector-0.2.1-20150608.041945-1.jar_info.json")); + + moduleListModel.addRepository(releaseRepo); + moduleListModel.addRepository(snapshotRepo); + moduleListModel.updateAllModules(); + } catch (IOException e) { + + } + } + + @BeforeAll + void setupDatabase() throws IOException, SQLException { + dataBase.createTable(SERVER_TABLE); + GeoLocation geo = geoService.resolve("localhost"); + firstEntry = new ServerEntry("localhost", 25000); + firstEntry.setName("myName"); + firstEntry.setOwner("Tester"); + firstEntry.setCountry(geo.getCountry()); + firstEntry.setStateprov(geo.getStateOrProvince()); + firstEntry.setCity(geo.getCity()); + dataBase.insert(SERVER_TABLE, firstEntry); + } +} diff --git a/src/test/java/org/terasology/master/JooqDbTest.java b/src/test/java/org/terasology/master/JooqDbTest.java index fa45d01..99142ed 100644 --- a/src/test/java/org/terasology/master/JooqDbTest.java +++ b/src/test/java/org/terasology/master/JooqDbTest.java @@ -16,38 +16,33 @@ package org.terasology.master; -import java.util.Map; - -import org.h2.jdbcx.JdbcDataSource; +import io.micronaut.test.annotation.MicronautTest; import org.junit.Assert; -import org.junit.Test; -import org.terasology.web.db.JooqDatabase; -import org.terasology.web.geo.GeoLocationService; - -public class JooqDbTest { +import org.junit.jupiter.api.Test; +import org.terasology.web.db.DataBase; - // Keep the content of an in-memory database as long as the virtual machine is alive - private static final String DB_URL = "jdbc:h2:mem:dbtest;DB_CLOSE_DELAY=-1"; +import javax.inject.Inject; +import java.util.Map; - @Test - public void testConnection() throws Exception { +@MicronautTest +class JooqDbTest { - JdbcDataSource ds = new JdbcDataSource(); - ds.setURL(DB_URL); + @Inject + DataBase db; - GeoLocationService geoService = new DummyGeoLocationService(); - JooqDatabase db = new JooqDatabase(ds, geoService); - String tableName = "servers"; + @Test + void testConnection() throws Exception { + String tableName = "servers1"; db.createTable(tableName); db.insert(tableName, "myName", "localhost", 25000, "Tester", true); Map data = db.readAll(tableName).get(0); - Assert.assertTrue(data.get("name").equals("myName")); - Assert.assertTrue(data.get("owner").equals("Tester")); - Assert.assertTrue(data.get("port").equals(25000)); - Assert.assertTrue(data.get("address").equals("localhost")); - Assert.assertTrue(data.get("active").equals(true)); + Assert.assertEquals("myName", data.get("name")); + Assert.assertEquals("Tester", data.get("owner")); + Assert.assertEquals(25000, data.get("port")); + Assert.assertEquals("localhost", data.get("address")); + Assert.assertEquals(true, data.get("active")); } } diff --git a/src/test/java/org/terasology/master/ModuleJsonListTest.java b/src/test/java/org/terasology/master/ModuleJsonListTest.java index 0155611..0275e33 100644 --- a/src/test/java/org/terasology/master/ModuleJsonListTest.java +++ b/src/test/java/org/terasology/master/ModuleJsonListTest.java @@ -16,47 +16,55 @@ package org.terasology.master; -import java.io.FileNotFoundException; +import com.google.gson.stream.JsonReader; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpStatus; +import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.annotation.Client; +import io.micronaut.http.client.exceptions.HttpClientResponseException; +import io.micronaut.test.annotation.MicronautTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.terasology.module.ModuleMetadata; +import org.terasology.module.ModuleMetadataJsonAdapter; +import org.terasology.naming.Name; +import org.terasology.naming.Version; + +import javax.inject.Inject; import java.io.IOException; -import java.io.InputStreamReader; import java.io.Reader; -import java.net.URL; +import java.io.StringReader; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.HashSet; import java.util.Set; -import org.junit.Assert; -import org.junit.Test; -import org.terasology.module.ModuleMetadata; -import org.terasology.module.ModuleMetadataJsonAdapter; -import org.terasology.naming.Name; -import org.terasology.naming.Version; - -import com.google.gson.stream.JsonReader; - /** * Tests the json operations in ModuleServlet. */ -public class ModuleJsonListTest extends WebServerBasedTests { +@MicronautTest +class ModuleJsonListTest extends BaseTests { private static final ModuleMetadataJsonAdapter META_READER = new ModuleMetadataJsonAdapter(); private final Charset charset = StandardCharsets.UTF_8; - @Test - public void testFullList() throws IOException { + @Inject + @Client("/") + HttpClient client; - URL url = new URL(URL_BASE + "/modules/list"); + @Test + void testFullList() throws IOException { + String response = client.toBlocking().retrieve(HttpRequest.GET("/modules/list")); - try (JsonReader reader = new JsonReader(new InputStreamReader(url.openStream(), charset))) { + try (JsonReader reader = new JsonReader(new StringReader(response))) { reader.beginArray(); while (reader.hasNext()) { ModuleMetadata meta = META_READER.read(reader); - Assert.assertNotNull(meta.getId()); - Assert.assertNotNull(meta.getVersion()); + Assertions.assertNotNull(meta.getId()); + Assertions.assertNotNull(meta.getVersion()); } reader.endArray(); @@ -64,20 +72,22 @@ public void testFullList() throws IOException { } @Test - public void testLatestList() throws IOException { + void testLatestList() throws IOException { - URL url = new URL(URL_BASE + "/modules/list/latest"); + String response = client.toBlocking().retrieve(HttpRequest.GET("/modules/list/latest")); Set ids = new HashSet<>(); - try (JsonReader reader = new JsonReader(new InputStreamReader(url.openStream(), charset))) { + try (JsonReader reader = new JsonReader(new StringReader(response))) { reader.beginArray(); while (reader.hasNext()) { ModuleMetadata meta = META_READER.read(reader); - Assert.assertNotNull(meta.getId()); - Assert.assertNotNull(meta.getVersion()); + Assertions.assertAll( + () -> Assertions.assertNotNull(meta.getId(), "Id must be provided"), + () -> Assertions.assertNotNull(meta.getVersion(), "Version must be provided"), - Assert.assertTrue("Only one latest version per module is possible", ids.add(meta.getId())); + () -> Assertions.assertTrue(ids.add(meta.getId()), "Only one latest version per module is possible") + ); } reader.endArray(); @@ -85,16 +95,16 @@ public void testLatestList() throws IOException { } @Test - public void testSingleModuleList() throws IOException { + void testSingleModuleList() throws IOException { - URL url = new URL(URL_BASE + "/modules/list/Core"); + String response = client.toBlocking().retrieve(HttpRequest.GET("/modules/list/Core")); - try (JsonReader reader = new JsonReader(new InputStreamReader(url.openStream(), charset))) { + try (JsonReader reader = new JsonReader(new StringReader(response))) { reader.beginArray(); while (reader.hasNext()) { ModuleMetadata meta = META_READER.read(reader); - Assert.assertEquals(new Name("Core"), meta.getId()); + Assertions.assertEquals(new Name("Core"), meta.getId()); } reader.endArray(); @@ -102,66 +112,62 @@ public void testSingleModuleList() throws IOException { } @Test - public void testSingleModuleVersion() throws IOException { + void testSingleModuleVersion() throws IOException { - URL url = new URL(URL_BASE + "/modules/list/Core/0.53.1"); + String response = client.toBlocking().retrieve(HttpRequest.GET("/modules/list/Core/0.53.1")); - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { + try (Reader reader = new StringReader(response)) { ModuleMetadata meta = META_READER.read(reader); - Assert.assertEquals(new Name("Core"), meta.getId()); - Assert.assertEquals(new Version("0.53.1"), meta.getVersion()); + Assertions.assertEquals(new Name("Core"), meta.getId()); + Assertions.assertEquals(new Version("0.53.1"), meta.getVersion()); } } - @Test(expected = FileNotFoundException.class) - public void testNonExistingModuleVersion() throws IOException { - - URL url = new URL(URL_BASE + "/modules/list/Core/23.1337.23"); - - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { - META_READER.read(reader); - } + @Test + void testNonExistingModuleVersion() throws IOException { + HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().retrieve(HttpRequest.GET("/modules/list/Core/23.1337.23")), + "Request to Not existiong module version should thrown an HttpClientResponseException" + ); + Assertions.assertEquals(HttpStatus.NOT_FOUND, exception.getStatus(), "Status must be 404"); } - @Test(expected = FileNotFoundException.class) - public void testInvalidVersion() throws IOException { - - URL url = new URL(URL_BASE + "/modules/list/Core/asdfd"); - - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { - META_READER.read(reader); - } + @Test + void testInvalidVersion() throws IOException { + HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().retrieve(HttpRequest.GET("/modules/list/Core/asdfd")), + "Request to invalid version should thrown an HttpClientResponseException" + ); + Assertions.assertEquals(HttpStatus.NOT_FOUND, exception.getStatus(), "Status must be 404"); } - @Test(expected = FileNotFoundException.class) - public void testUnknownModuleLatestVersion() throws IOException { - - URL url = new URL(URL_BASE + "/modules/list/notThere/latest"); - - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { - META_READER.read(reader); - } + @Test + void testUnknownModuleLatestVersion() throws IOException { + HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().retrieve(HttpRequest.GET("/modules/list/notThere/latest")), + "Request to Unknown Module Version should thrown an HttpClientResponseException" + ); + Assertions.assertEquals(HttpStatus.NOT_FOUND, exception.getStatus(), "Status must be 404"); } - @Test(expected = FileNotFoundException.class) - public void testUnknownModuleInvalidVersion() throws IOException { - - URL url = new URL(URL_BASE + "/modules/list/notThere/1.2.3"); - - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { - META_READER.read(reader); - } + @Test + void testUnknownModuleInvalidVersion() throws IOException { + HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().retrieve(HttpRequest.GET("/modules/list/notThere/1.2.3")), + "Request to unknown module should thrown an HttpClientResponseException" + ); + Assertions.assertEquals(HttpStatus.NOT_FOUND, exception.getStatus(), "Status must be 404"); } @Test - public void testSingleModuleLatestVersion() throws IOException { + void testSingleModuleLatestVersion() throws IOException { - URL url = new URL(URL_BASE + "/modules/list/Core/latest"); + String response = client.toBlocking().retrieve(HttpRequest.GET("/modules/list/Core/latest")); - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { + try (Reader reader = new StringReader(response)) { ModuleMetadata meta = META_READER.read(reader); - Assert.assertEquals(new Name("Core"), meta.getId()); - Assert.assertEquals(new Version("0.53.1"), meta.getVersion()); + Assertions.assertEquals(new Name("Core"), meta.getId()); + Assertions.assertEquals(new Version("0.53.1"), meta.getVersion()); } } } diff --git a/src/test/java/org/terasology/master/ModuleShowTest.java b/src/test/java/org/terasology/master/ModuleShowTest.java index 1d9b8f8..4af2b71 100644 --- a/src/test/java/org/terasology/master/ModuleShowTest.java +++ b/src/test/java/org/terasology/master/ModuleShowTest.java @@ -16,60 +16,66 @@ package org.terasology.master; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpStatus; +import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.annotation.Client; +import io.micronaut.http.client.exceptions.HttpClientResponseException; +import io.micronaut.test.annotation.MicronautTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import javax.inject.Inject; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import org.junit.Test; - /** * */ -public class ModuleShowTest extends WebServerBasedTests { +@MicronautTest +class ModuleShowTest extends BaseTests { private final Charset charset = StandardCharsets.UTF_8; - @Test(expected = FileNotFoundException.class) - public void testNonExistingModuleVersion() throws IOException { + @Inject + @Client("/") + HttpClient client; - URL url = new URL(URL_BASE + "/modules/show/Core/23.1337.23"); - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { - reader.read(); - } + @Test + void testNonExistingModuleVersion() { + HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().retrieve(HttpRequest.GET("/modules/show/Core/23.1337.23")), + "Request to not existing moduel version should thrown an HttpClientResponseException" + ); + Assertions.assertEquals(HttpStatus.NOT_FOUND, exception.getStatus(), "Status must be 404"); } - @Test(expected = FileNotFoundException.class) - public void testInvalidVersion() throws IOException { - - URL url = new URL(URL_BASE + "/modules/show/Core/sdfsdfs"); - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { - reader.read(); - } + @Test + void testInvalidVersion() { + HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().retrieve(HttpRequest.GET("/modules/show/Core/sdfdsad")), + "Request to unknown module should thrown an HttpClientResponseException" + ); + Assertions.assertEquals(HttpStatus.NOT_FOUND, exception.getStatus(), "Status must be 404"); } - @Test(expected = FileNotFoundException.class) - public void testUnknownModuleLatestVersion() throws IOException { - - URL url = new URL(URL_BASE + "/modules/show/notThere/latest"); - - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { - reader.read(); - } + @Test + void testUnknownModuleLatestVersion() { + HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().retrieve(HttpRequest.GET("/modules/show/notThere/latest")), + "Request to invalid version should thrown an HttpClientResponseException" + ); + Assertions.assertEquals(HttpStatus.NOT_FOUND, exception.getStatus(), "Status must be 404"); } - @Test(expected = FileNotFoundException.class) - public void testUnknownModuleInvalidVersion() throws IOException { - - URL url = new URL(URL_BASE + "/modules/show/notThere/1.2.3"); - - try (Reader reader = new InputStreamReader(url.openStream(), charset)) { - reader.read(); - } + @Test + void testUnknownModuleInvalidVersion() { + HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, + () -> client.toBlocking().retrieve(HttpRequest.GET("/modules/show/notThere/1.2.3")), + "Request to unknown module should thrown an HttpClientResponseException" + ); + Assertions.assertEquals(HttpStatus.NOT_FOUND, exception.getStatus(), "Status must be 404"); } } diff --git a/src/test/java/org/terasology/master/ModuleUpdateTest.java b/src/test/java/org/terasology/master/ModuleUpdateTest.java index 08169e0..378da59 100644 --- a/src/test/java/org/terasology/master/ModuleUpdateTest.java +++ b/src/test/java/org/terasology/master/ModuleUpdateTest.java @@ -16,58 +16,60 @@ package org.terasology.master; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.Reader; -import java.net.HttpURLConnection; +import com.google.gson.stream.JsonReader; +import io.micronaut.core.io.IOUtils; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.annotation.Client; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.terasology.module.ModuleMetadata; +import org.terasology.module.ModuleMetadataJsonAdapter; + +import javax.inject.Inject; +import javax.ws.rs.core.Response.Status; +import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import javax.ws.rs.core.Response.Status; - -import org.junit.Assert; -import org.junit.Test; -import org.terasology.module.ModuleMetadata; -import org.terasology.module.ModuleMetadataJsonAdapter; - -import com.google.common.io.ByteStreams; -import com.google.gson.stream.JsonReader; - -public class ModuleUpdateTest extends WebServerBasedTests { +class ModuleUpdateTest extends BaseTests { private final ModuleMetadataJsonAdapter adapter = new ModuleMetadataJsonAdapter(); + @Inject + @Client("/") + HttpClient client; + @Test - public void testUpdate() throws MalformedURLException, IOException { + void testUpdate() throws MalformedURLException, IOException { - Assert.assertEquals(0, readJsonList("/modules/list/CommonWorld").size()); + Assertions.assertEquals(0, readJsonList("/modules/list/CommonWorld").size()); - addSnapshot("CommonWorld", "CommonWorld-0.1.2-20150419.030003-8.jar_info.json"); + snapshotRepo.addArtifact("CommonWorld", new ClasspathArtifactInfo("/metas/" + "CommonWorld-0.1.2-20150419.030003-8.jar_info.json")); ModuleMetadata snapshot012 = readFromClasspath("CommonWorld-0.1.2-20150419.030003-8.jar_info.json"); // send update notification String classpathFile = "/jenkins/CommonWorld-jenkins-notification.json"; - int responseCode = postNotification(new URL(URL_BASE + "/modules/update"), classpathFile); + int responseCode = postNotification("/modules/update", classpathFile); - Assert.assertEquals(Status.OK.getStatusCode(), responseCode); - Assert.assertEquals(1, readJsonList("/modules/list/CommonWorld").size()); - Assert.assertEquals(snapshot012, readJsonList("/modules/list/CommonWorld").get(0)); + Assertions.assertEquals(Status.OK.getStatusCode(), responseCode); + Assertions.assertEquals(1, readJsonList("/modules/list/CommonWorld").size()); + Assertions.assertEquals(snapshot012, readJsonList("/modules/list/CommonWorld").get(0)); - addSnapshot("CommonWorld", "CommonWorld-0.1.3-20150608.034751-1.jar_info.json"); + snapshotRepo.addArtifact("CommonWorld", new ClasspathArtifactInfo("/metas/" + "CommonWorld-0.1.3-20150608.034751-1.jar_info.json")); // send 2nd update notification - responseCode = postNotification(new URL(URL_BASE + "/modules/update"), classpathFile); - Assert.assertEquals(Status.OK.getStatusCode(), responseCode); + responseCode = postNotification("/modules/update", classpathFile); + Assertions.assertEquals(Status.OK.getStatusCode(), responseCode); - Assert.assertEquals(2, readJsonList("/modules/list/CommonWorld").size()); + Assertions.assertEquals(2, readJsonList("/modules/list/CommonWorld").size()); -// ModuleMetadata snapshot013 = readFromClasspath("CommonWorld-0.1.3-20150608.034751-1.jar_info.json"); -// Assert.assertEquals(snapshot013, readJsonList("/modules/list/CommonWorld").get(0)); + ModuleMetadata snapshot013 = readFromClasspath("CommonWorld-0.1.3-20150608.034751-1.jar_info.json"); + Assertions.assertEquals(snapshot013, readJsonList("/modules/list/CommonWorld").get(0)); } private ModuleMetadata readFromClasspath(String path) throws IOException { @@ -78,10 +80,10 @@ private ModuleMetadata readFromClasspath(String path) throws IOException { } private List readJsonList(String path) throws IOException { - URL url = new URL(URL_BASE + path); + String response = client.toBlocking().retrieve(HttpRequest.GET(path)); List result = new ArrayList<>(); - try (Reader in = new InputStreamReader(url.openStream(), StandardCharsets.UTF_8); + try (Reader in = new StringReader(response); JsonReader reader = new JsonReader(in)) { reader.beginArray(); @@ -95,20 +97,12 @@ private List readJsonList(String path) throws IOException { return result; } - private int postNotification(URL url, String classpathFile) throws IOException { - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - - // or manually with curl: + private int postNotification(String path, String classpathFile) throws IOException { // curl -X POST -d @ --header "Content-Type:application/json" - connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); - connection.setDoInput(true); - connection.setDoOutput(true); - connection.connect(); - try (OutputStream output = connection.getOutputStream(); - InputStream input = getClass().getResourceAsStream(classpathFile)) { - ByteStreams.copy(input, output); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(classpathFile)))) { + String notificationBody = IOUtils.readText(reader); + HttpResponse response = client.toBlocking().exchange(HttpRequest.POST(path, notificationBody)); + return response.code(); } - - return connection.getResponseCode(); } } diff --git a/src/test/java/org/terasology/master/ServerHtmlContentTest.java b/src/test/java/org/terasology/master/ServerHtmlContentTest.java index 3c32eaf..edfc3fd 100644 --- a/src/test/java/org/terasology/master/ServerHtmlContentTest.java +++ b/src/test/java/org/terasology/master/ServerHtmlContentTest.java @@ -16,25 +16,31 @@ package org.terasology.master; -import java.io.IOException; - +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.annotation.Client; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import javax.inject.Inject; /** * */ -public class ServerHtmlContentTest extends WebServerBasedTests { +public class ServerHtmlContentTest extends BaseTests { - @Test - public void testShowHtml() throws IOException { - String url = URL_BASE + "/servers/show"; + @Inject + @Client("/") + HttpClient client; - Document doc = Jsoup.connect(url).get(); + @Test + public void testShowHtml() { + String response = client.toBlocking().retrieve(HttpRequest.GET("/servers/show")); + Document doc = Jsoup.parse(response); Element table = doc.getElementById("server-list"); Assert.assertTrue(table.nodeName().equals("table")); diff --git a/src/test/java/org/terasology/master/ServerJsonListTest.java b/src/test/java/org/terasology/master/ServerJsonListTest.java index 485c1b5..517030a 100644 --- a/src/test/java/org/terasology/master/ServerJsonListTest.java +++ b/src/test/java/org/terasology/master/ServerJsonListTest.java @@ -16,45 +16,47 @@ package org.terasology.master; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.annotation.Client; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.terasology.web.model.ServerEntry; + +import javax.inject.Inject; import java.io.IOException; -import java.io.InputStreamReader; import java.io.Reader; +import java.io.StringReader; import java.lang.reflect.Type; -import java.net.MalformedURLException; -import java.net.URL; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.List; -import org.junit.Assert; -import org.junit.Test; -import org.terasology.web.model.ServerEntry; - -import com.google.common.reflect.TypeToken; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - /** * */ -public class ServerJsonListTest extends WebServerBasedTests { +class ServerJsonListTest extends BaseTests { private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + @Inject + @Client("/") + HttpClient client; + @Test - public void testJson() throws MalformedURLException { + void testJson() { @SuppressWarnings("serial") - Type entryListType = new TypeToken>() { /**/ }.getType(); + Type entryListType = new TypeToken>() { /**/ + }.getType(); - URL url = new URL(URL_BASE + "/servers/list"); - Charset cs = StandardCharsets.UTF_8; - try (Reader reader = new InputStreamReader(url.openStream(), cs)) { + try (Reader reader = new StringReader(client.toBlocking().retrieve(HttpRequest.GET("/servers/list")))) { List list = GSON.fromJson(reader, entryListType); ServerEntry entry = list.get(0); - Assert.assertEquals(entry, firstEntry); + Assertions.assertEquals(firstEntry, entry); } catch (IOException e) { e.printStackTrace(); diff --git a/src/test/java/org/terasology/master/ValidatorTests.java b/src/test/java/org/terasology/master/ValidatorTests.java index bdd582c..fd5c06b 100644 --- a/src/test/java/org/terasology/master/ValidatorTests.java +++ b/src/test/java/org/terasology/master/ValidatorTests.java @@ -16,87 +16,61 @@ package org.terasology.master; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.charset.StandardCharsets; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.io.CharStreams; import com.jcabi.w3c.Defect; import com.jcabi.w3c.ValidationResponse; import com.jcabi.w3c.Validator; import com.jcabi.w3c.ValidatorBuilder; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.HttpClient; +import io.micronaut.http.client.annotation.Client; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Inject; +import java.io.IOException; /** * Use the w3c validator to verify that correct html code is generated. */ -public class ValidatorTests extends WebServerBasedTests { - - private static final Logger logger = LoggerFactory.getLogger(ValidatorTests.class); - - private static Validator validator; - - @BeforeClass - public static void createValidator() { - validator = new ValidatorBuilder().html(); - } - - @Test - public void testShowListAllPage() throws IOException { - analyzePage(new URL(URL_BASE + "/modules/show")); - } - @Test - public void testShowModulePage() throws IOException { - analyzePage(new URL(URL_BASE + "/modules/show/Core")); - } +class ValidatorTests extends BaseTests { - @Test - public void testShowModuleInfoPage() throws IOException { - analyzePage(new URL(URL_BASE + "/modules/show/Core/0.53.1")); - } - - @Test - public void testShowServerListPage() throws IOException { - analyzePage(new URL(URL_BASE + "/servers/show")); - } - - @Test - public void testShowAboutPage() throws IOException { - analyzePage(new URL(URL_BASE + "/home")); - } - - @Test - public void testShowAddServerPage() throws IOException { - analyzePage(new URL(URL_BASE + "/servers/add")); - } + private static final Logger logger = LoggerFactory.getLogger(ValidatorTests.class); - @Test - public void testShowEditServerPage() throws IOException { - analyzePage(new URL(URL_BASE + "/servers/edit?index=0")); + private static Validator validator = new ValidatorBuilder().html(); + + @Inject + @Client("/") + HttpClient client; + + @ParameterizedTest() + @ValueSource(strings = { + "/modules/show", + "/modules/show/Core", + "/modules/show/Core/0.53.1", + "/servers/show", + "/home", + "/servers/add", + "/servers/edit?index=0", + }) + void testW3CValidation(String uri) throws IOException { + analyzePage(uri); } - private void analyzePage(URL url) throws IOException { - try (InputStream is = url.openStream()) { - InputStreamReader inr = new InputStreamReader(is, StandardCharsets.UTF_8); - String text = CharStreams.toString(inr); - ValidationResponse response = validator.validate(text); - if (!response.valid()) { - for (Defect error : response.warnings()) { - logger.warn(error.toString()); - } - for (Defect error : response.errors()) { - logger.error("ERROR: " + error.toString()); - } - Assert.fail(); + private void analyzePage(String uri) throws IOException { + String text = client.toBlocking().retrieve(HttpRequest.GET(uri)); + ValidationResponse response = validator.validate(text); + if (!response.valid()) { + for (Defect error : response.warnings()) { + logger.warn(error.toString()); + } + for (Defect error : response.errors()) { + logger.error("ERROR: " + error.toString()); } + Assertions.fail("W3C Validation failed, see logs"); } } } diff --git a/src/test/java/org/terasology/master/WebServerBasedTests.java b/src/test/java/org/terasology/master/WebServerBasedTests.java deleted file mode 100644 index 71edc4d..0000000 --- a/src/test/java/org/terasology/master/WebServerBasedTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.terasology.master; - -import org.eclipse.jetty.server.Server; -import org.h2.jdbcx.JdbcDataSource; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.TemporaryFolder; -import org.terasology.web.JettyMain; -import org.terasology.web.artifactory.ArtifactRepository.RepoType; -import org.terasology.web.db.DataBase; -import org.terasology.web.db.JooqDatabase; -import org.terasology.web.geo.GeoLocation; -import org.terasology.web.geo.GeoLocationService; -import org.terasology.web.model.ModuleListModelImpl; -import org.terasology.web.model.ServerEntry; -import org.terasology.web.model.ServerListModel; -import org.terasology.web.model.ServerListModelImpl; -import org.terasology.web.servlet.AboutController; -import org.terasology.web.servlet.ServerServlet; - -import java.io.File; -import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.util.concurrent.atomic.AtomicInteger; - -public abstract class WebServerBasedTests { - - @ClassRule - public static TemporaryFolder tempFolder = new TemporaryFolder(); - - protected static final int PORT = 8082; - protected static final String URL_BASE = "http://localhost:" + PORT; - protected static final String SERVER_TABLE = "servers"; - protected static ServerEntry firstEntry; - - private static DataBase dataBase; - private static Server webServer; - private static Connection dummyConn; - private static AtomicInteger atomCount = new AtomicInteger(); - - private static DummyArtifactRepo releaseRepo; - private static DummyArtifactRepo snapshotRepo; - - @BeforeClass - public static void setup() throws Exception { - - String secret = "edit"; - - // make a unique database for each testing class - String dbUri = "jdbc:h2:mem:test_" + atomCount.getAndIncrement(); - - JdbcDataSource ds = new JdbcDataSource(); - ds.setURL(dbUri); - - GeoLocationService geoService = new DummyGeoLocationService(); - - // Open a dummy connection to the in-memory database to keep it alive - dummyConn = DriverManager.getConnection(dbUri); - dataBase = new JooqDatabase(ds, geoService); - - File cacheFolder = tempFolder.newFolder("module", "cache"); - ModuleListModelImpl moduleListModel = new ModuleListModelImpl(cacheFolder.toPath(), new DummyExtractor()); - - releaseRepo = new DummyArtifactRepo(RepoType.RELEASE); - addRelease("Core", "Core-0.53.1.jar_info.json"); - - snapshotRepo = new DummyArtifactRepo(RepoType.SNAPSHOT); - addSnapshot("ChrisVolume1OST", "ChrisVolume1OST-0.2.1-20150608.034649-1.jar_info.json"); - addSnapshot("MusicDirector", "MusicDirector-0.2.1-20150608.041945-1.jar_info.json"); - - moduleListModel.addRepository(releaseRepo); - moduleListModel.addRepository(snapshotRepo); - - moduleListModel.updateAllModules(); - - ServerListModel serverListModel = new ServerListModelImpl(dataBase, SERVER_TABLE, secret); - - webServer = JettyMain.createServer(PORT, - new AboutController(), - new ServerServlet(serverListModel)); // the server list servlet -// new ModuleServlet(moduleListModel)); // the module list servlet - - webServer.start(); - - dataBase.createTable(SERVER_TABLE); - - GeoLocation geo = geoService.resolve("localhost"); - firstEntry = new ServerEntry("localhost", 25000); - firstEntry.setName("myName"); - firstEntry.setOwner("Tester"); - firstEntry.setCountry(geo.getCountry()); - firstEntry.setStateprov(geo.getStateOrProvince()); - firstEntry.setCity(geo.getCity()); - dataBase.insert(SERVER_TABLE, firstEntry); - } - - protected static void addRelease(String modName, String fname) throws IOException { - releaseRepo.addArtifact(modName, new ClasspathArtifactInfo("/metas/" + fname)); - } - - protected static void addSnapshot(String modName, String fname) throws IOException { - snapshotRepo.addArtifact(modName, new ClasspathArtifactInfo("/metas/" + fname)); - } - - @AfterClass - public static void shutdown() throws Exception { - webServer.stop(); - dummyConn.close(); - } -} diff --git a/src/test/java/org/terasology/master/DummyArtifactRepo.java b/src/test/java/org/terasology/master/services/DummyArtifactRepo.java similarity index 91% rename from src/test/java/org/terasology/master/DummyArtifactRepo.java rename to src/test/java/org/terasology/master/services/DummyArtifactRepo.java index f4abf10..1906c9f 100644 --- a/src/test/java/org/terasology/master/DummyArtifactRepo.java +++ b/src/test/java/org/terasology/master/services/DummyArtifactRepo.java @@ -14,18 +14,14 @@ * limitations under the License. */ -package org.terasology.master; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; +package org.terasology.master.services; import org.terasology.web.artifactory.ArtifactInfo; import org.terasology.web.artifactory.ArtifactRepository; +import java.io.IOException; +import java.util.*; + public class DummyArtifactRepo implements ArtifactRepository { private final RepoType type; diff --git a/src/test/java/org/terasology/master/DummyExtractor.java b/src/test/java/org/terasology/master/services/DummyExtractor.java similarity index 88% rename from src/test/java/org/terasology/master/DummyExtractor.java rename to src/test/java/org/terasology/master/services/DummyExtractor.java index 711802c..d9677c6 100644 --- a/src/test/java/org/terasology/master/DummyExtractor.java +++ b/src/test/java/org/terasology/master/services/DummyExtractor.java @@ -14,21 +14,26 @@ * limitations under the License. */ -package org.terasology.master; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; +package org.terasology.master.services; +import io.micronaut.context.annotation.Replaces; import org.terasology.module.ModuleMetadata; import org.terasology.module.ModuleMetadataJsonAdapter; import org.terasology.module.RemoteModuleExtension; import org.terasology.web.model.MetadataExtractor; +import org.terasology.web.model.ZipExtractor; + +import javax.inject.Singleton; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; /** * Reads metadata from metadata files as-is. */ +@Replaces(ZipExtractor.class) +@Singleton public class DummyExtractor implements MetadataExtractor { private final ModuleMetadataJsonAdapter metaReader = new ModuleMetadataJsonAdapter(); diff --git a/src/test/java/org/terasology/master/DummyGeoLocationService.java b/src/test/java/org/terasology/master/services/DummyGeoLocationService.java similarity index 91% rename from src/test/java/org/terasology/master/DummyGeoLocationService.java rename to src/test/java/org/terasology/master/services/DummyGeoLocationService.java index a41b5bc..dfff403 100644 --- a/src/test/java/org/terasology/master/DummyGeoLocationService.java +++ b/src/test/java/org/terasology/master/services/DummyGeoLocationService.java @@ -14,15 +14,20 @@ * limitations under the License. */ -package org.terasology.master; +package org.terasology.master.services; -import java.io.IOException; +import io.micronaut.context.annotation.Primary; import org.terasology.web.geo.GeoLocation; import org.terasology.web.geo.GeoLocationService; +import javax.inject.Singleton; +import java.io.IOException; + /** * A dummy implementation of {@link GeoLocationService}. */ +@Primary +@Singleton public class DummyGeoLocationService implements GeoLocationService { @Override From 1f2066fedc4659d88475949231ef4595bd2d1bcd Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 12:54:15 +0300 Subject: [PATCH 03/20] migration(micronauts): remove JettyMain, edit Readme. --- README.md | 8 +- .../java/org/terasology/web/JettyMain.java | 179 ------------------ .../web/geo/dbip/GeoLocationServiceDbIp.java | 5 +- .../web/model/ModuleListModelImpl.java | 2 +- .../web/model/ServerListModelImpl.java | 4 +- src/main/resources/application-test.yml | 5 +- src/main/resources/application.yml | 6 +- 7 files changed, 18 insertions(+), 191 deletions(-) delete mode 100644 src/main/java/org/terasology/web/JettyMain.java diff --git a/README.md b/README.md index eb718b6..fbe088f 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ Deployment Heroku: Clone the repository and push the content to Heroku on branch `master`. Some details must be provided through environment variables: - DATABASE_URL=postgres://name:pw@host:port/database - PORT=8080 - DBIP_API_KEY= - EDIT_SECRET= + DATASOURCE_DEFAULT_URL=postgres://name:pw@host:port/database + SERVER_URL=8080 + META_SERVER_DBIP_API_KEY= + META_SERVER_EDIT_SECRET= Geo-Location ------------- diff --git a/src/main/java/org/terasology/web/JettyMain.java b/src/main/java/org/terasology/web/JettyMain.java deleted file mode 100644 index 4944baf..0000000 --- a/src/main/java/org/terasology/web/JettyMain.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.terasology.web; - -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.server.handler.HandlerList; -import org.eclipse.jetty.server.handler.ResourceHandler; -import org.eclipse.jetty.servlet.FilterHolder; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.eclipse.jetty.servlet.ServletHolder; -import org.eclipse.jetty.servlets.CrossOriginFilter; -import org.glassfish.jersey.server.ResourceConfig; -import org.glassfish.jersey.servlet.ServletContainer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.terasology.web.db.DataBase; -import org.terasology.web.db.JooqDatabase; -import org.terasology.web.geo.GeoLocationService; -import org.terasology.web.geo.dbip.GeoLocationServiceDbIp; -import org.terasology.web.io.GsonMessageBodyHandler; -import org.terasology.web.model.ServerListModel; -import org.terasology.web.model.ServerListModelImpl; - -import javax.servlet.DispatcherType; -import java.net.URI; -import java.util.EnumSet; -import java.util.Locale; - - -/** - */ -public final class JettyMain { - - private static final Logger logger = LoggerFactory.getLogger(JettyMain.class); - - private JettyMain() { - // no instances - } - - /** - * @param args ignored - * @throws Exception - */ - public static void main(String[] args) throws Exception { - - String portEnv = System.getenv("PORT"); - if (portEnv == null) { - portEnv = "8080"; - logger.warn("Environment variable 'PORT' not defined - using default {}", portEnv); - } - Integer port = Integer.valueOf(portEnv); - - String dbEnv = System.getenv("DATABASE_URL"); - if (dbEnv == null) { - logger.error("Environment variable 'DATABASE_URL' not defined!"); - return; - } - URI dbUri = new URI(dbEnv); - - String secret = System.getenv("EDIT_SECRET"); - if (secret == null) { - logger.error("Environment variable 'EDIT_SECRET' not defined!"); - return; - } - - String dbIpApiKey = System.getenv("DBIP_API_KEY"); - if (dbIpApiKey == null) { - logger.warn("Environment variable 'DBIP_API_KEY' not defined - geo location lookup not available"); - } - - String username = dbUri.getUserInfo().split(":")[0]; - String password = dbUri.getUserInfo().split(":")[1]; - int dbPort = dbUri.getPort(); - - String host = "http://artifactory.terasology.org/artifactory"; - String releaseRepo = "terasology-release-local"; - String snapshotRepo = "terasology-snapshot-local"; - String modGroup = "org.terasology.modules"; - String engineGroup = "org.terasology.engine"; -// -// ModuleListModelImpl moduleListModel = new ModuleListModelImpl(cacheFolder); -// Path releaseRepoFolder = cacheFolder.resolve(releaseRepo); -// Path snapshotRepoFolder = cacheFolder.resolve(snapshotRepo); -// -// // add module repos -// moduleListModel.addRepository(ArtifactoryRepo.release(host, releaseRepo, modGroup, releaseRepoFolder)); -// moduleListModel.addRepository(ArtifactoryRepo.snapshot(host, snapshotRepo, modGroup, snapshotRepoFolder)); -// -// // add engine repos -// moduleListModel.addRepository(ArtifactoryRepo.release(host, releaseRepo, engineGroup, releaseRepoFolder)); -// moduleListModel.addRepository(ArtifactoryRepo.snapshot(host, snapshotRepo, engineGroup, snapshotRepoFolder)); - - HikariConfig config = new HikariConfig(); - config.setJdbcUrl("jdbc:postgresql://" + dbUri.getHost() + ":" + dbPort + dbUri.getPath()); - config.setUsername(username); - config.setPassword(password); - config.addDataSourceProperty("sslmode", "require"); - config.setMaximumPoolSize(3); - config.setMinimumIdle(1); - - GeoLocationService geoService = new GeoLocationServiceDbIp(dbIpApiKey); - - // this is mostly for I18nMap, but can have an influence on other - // string formats. Note that metainfo.ftl explicitly sets the locale to - // define the date format. - Locale.setDefault(Locale.ENGLISH); - - try (HikariDataSource ds = new HikariDataSource(config)) { - - DataBase dataBase = new JooqDatabase(ds, geoService); - ServerListModel serverListModel = new ServerListModelImpl(dataBase, "servers", secret); - - logger.info("Server started on port {}!", port); - -// new Thread(moduleListModel::updateAllModules).start(); - - // server.join(); - } - } - - public static Server createServer(int port, Object... servlets) throws Exception { - Server server = new Server(port); - - ResourceHandler logFileResourceHandler = new ResourceHandler(); - logFileResourceHandler.setDirectoriesListed(true); - logFileResourceHandler.setResourceBase("logs"); - - ContextHandler logContext = new ContextHandler("/logs"); // the server uri path - logContext.setHandler(logFileResourceHandler); - - ResourceHandler webResourceHandler = new ResourceHandler(); - webResourceHandler.setDirectoriesListed(false); - webResourceHandler.setResourceBase("web"); - - ContextHandler webContext = new ContextHandler("/"); // the server uri path - webContext.setHandler(webResourceHandler); - - ResourceConfig rc = new ResourceConfig(); - rc.register(new GsonMessageBodyHandler()); // register JSON serializer - - for (Object servlet : servlets) { - rc.register(servlet); - } - - ServletContextHandler jerseyContext = new ServletContextHandler(ServletContextHandler.SESSIONS); - jerseyContext.setContextPath("/"); - jerseyContext.setResourceBase("templates"); - jerseyContext.addServlet(new ServletHolder(new ServletContainer(rc)), "/*"); - - FilterHolder holder = new FilterHolder(new CrossOriginFilter()); - jerseyContext.addFilter(holder, "/*", EnumSet.of(DispatcherType.REQUEST)); - - HandlerList handlers = new HandlerList(); - handlers.addHandler(logContext); - handlers.addHandler(webContext); - handlers.addHandler(jerseyContext); - - server.setHandler(handlers); - - return server; - } -} diff --git a/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java b/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java index 0897e16..7528ad6 100644 --- a/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java +++ b/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java @@ -16,6 +16,7 @@ package org.terasology.web.geo.dbip; +import io.micronaut.context.annotation.Value; import org.terasology.web.geo.GeoLocation; import org.terasology.web.geo.GeoLocationService; import retrofit.RestAdapter; @@ -33,7 +34,9 @@ public class GeoLocationServiceDbIp implements GeoLocationService { private final String apiKey; - public GeoLocationServiceDbIp(String apiKey) { + public GeoLocationServiceDbIp( + @Value("meta-server.dbip.api.key") String apiKey + ) { this.apiKey = apiKey; } diff --git a/src/main/java/org/terasology/web/model/ModuleListModelImpl.java b/src/main/java/org/terasology/web/model/ModuleListModelImpl.java index ebf140e..2185df8 100644 --- a/src/main/java/org/terasology/web/model/ModuleListModelImpl.java +++ b/src/main/java/org/terasology/web/model/ModuleListModelImpl.java @@ -61,7 +61,7 @@ public class ModuleListModelImpl implements ModuleListModel { private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); public ModuleListModelImpl( - @Value("${meta-server.cacheFolder}") Path cacheFolder, + @Value("${meta-server.cache.folder}") Path cacheFolder, MetadataExtractor extractor) { this.cacheFolder = cacheFolder; this.cacheFolder.toFile().mkdirs(); diff --git a/src/main/java/org/terasology/web/model/ServerListModelImpl.java b/src/main/java/org/terasology/web/model/ServerListModelImpl.java index b2b9b55..12f19be 100644 --- a/src/main/java/org/terasology/web/model/ServerListModelImpl.java +++ b/src/main/java/org/terasology/web/model/ServerListModelImpl.java @@ -41,8 +41,8 @@ public class ServerListModelImpl implements ServerListModel { private final String editSecret; public ServerListModelImpl(DataBase dataBase, - @Value("${meta-server.tableName}") String tableName, - @Value("${meta-server.editSecret}") String editSecret) throws SQLException { + @Value("${meta-server.table.name}") String tableName, + @Value("${meta-server.edit.secret}") String editSecret) throws SQLException { Preconditions.checkArgument(dataBase != null, "dataSource must not be null"); Preconditions.checkArgument(tableName != null, "tableName must not be null"); Preconditions.checkArgument(editSecret != null, "editSecret must not be null"); diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 3446f47..3a2da3f 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -3,4 +3,7 @@ datasources: url: jdbc:h2:mem:testdb driverClassName: org.h2.Driver username: sa - password: password \ No newline at end of file + password: password + +meta-server: + edit.secret: "foo" diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 90abaf9..0aa78fb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -14,6 +14,6 @@ datasources: password: '' meta-server: - cacheFolder: "./cache" - tableName: "servers" - editSecret: "foobar" + cache.folder: "./cache" + table.name: "servers" + From c6fa408020b631b229c70da109da133c40ddbdc3 Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 13:07:23 +0300 Subject: [PATCH 04/20] migration(micronauts): remove jax-rs and jersey libs from dependencies --- build.gradle | 52 ++++----- .../web/io/GsonMessageBodyHandler.java | 109 ------------------ .../org/terasology/master/JooqDbTest.java | 12 +- .../terasology/master/ModuleUpdateTest.java | 12 +- .../master/ServerHtmlContentTest.java | 12 +- 5 files changed, 40 insertions(+), 157 deletions(-) delete mode 100644 src/main/java/org/terasology/web/io/GsonMessageBodyHandler.java diff --git a/build.gradle b/build.gradle index 4e1e7fa..cac5199 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,6 @@ configurations { } dependencies { - /* Micronauts start*/ annotationProcessor(platform("io.micronaut:micronaut-bom:$micronautVersion")) annotationProcessor("io.micronaut:micronaut-inject-java") annotationProcessor("io.micronaut:micronaut-validation") @@ -63,52 +62,45 @@ dependencies { implementation("io.micronaut.sql:micronaut-jooq") runtimeOnly("ch.qos.logback:logback-classic") runtimeOnly("org.postgresql:postgresql") - testAnnotationProcessor(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")) - testAnnotationProcessor("io.micronaut:micronaut-inject-java") - testImplementation(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")) - testImplementation("org.junit.jupiter:junit-jupiter-api") - testImplementation("org.junit.jupiter:junit-jupiter-params") - testImplementation("io.micronaut.test:micronaut-test-junit5") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") - -// testImplementation(platform("org.testcontainers:testcontainers-bom:1.14.3")) -// testRuntimeOnly("org.testcontainers:postgresql") - /* Micronauts end*/ + + implementation 'org.slf4j:slf4j-api:1.7.30' - implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: jettyVersion - implementation group: 'org.eclipse.jetty', name: 'jetty-servlets', version: jettyVersion - implementation 'javax.servlet:javax.servlet-api:3.1.0' + // For `@ThreadSafe` implementation 'javax.annotation:javax.annotation-api:1.3.2' implementation 'com.google.code.findbugs:jsr305:3.0.0' - implementation 'org.glassfish.jersey.containers:jersey-container-jetty-servlet:2.22.1' - + // Module working implementation 'com.google.code.gson:gson:2.4' - implementation 'com.google.guava:guava:18.0' + implementation 'org.terasology:gestalt-module:4.1.2' - implementation 'org.jooq:jooq:3.7.0' - implementation 'org.postgresql:postgresql:9.4-1205-jdbc42' + implementation 'com.google.guava:guava:18.0' + //Service like rest client. implementation 'com.squareup.retrofit:retrofit:1.9.0' + + //// Tests + testAnnotationProcessor(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")) + testAnnotationProcessor("io.micronaut:micronaut-inject-java") + testImplementation(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")) - implementation 'org.slf4j:slf4j-api:1.7.30' - - implementation 'com.zaxxer:HikariCP:2.4.1' - - implementation 'org.terasology:gestalt-module:4.1.2' + //Junit 5 + testImplementation("org.junit.jupiter:junit-jupiter-api") + testImplementation("org.junit.jupiter:junit-jupiter-params") + testImplementation("io.micronaut.test:micronaut-test-junit5") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") + // html validation testImplementation 'org.jsoup:jsoup:1.8.3' testImplementation 'com.jcabi:jcabi-w3c:1.3' testImplementation 'com.jcabi:jcabi-matchers:1.4' - testImplementation 'junit:junit:4.12' - testImplementation("com.h2database:h2") - testImplementation 'org.slf4j:slf4j-api:1.7.30' - runtimeOnly group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.3' + // loggin and database + testImplementation 'org.slf4j:slf4j-api:1.7.30' + testImplementation 'com.h2database:h2' + // Code analyzers pmd 'net.sourceforge.pmd:pmd-core:6.27.0' pmd 'net.sourceforge.pmd:pmd-java:6.27.0' - codeMetrics group: 'org.terasology.config', name: 'codemetrics', version: '1.3.2', ext: 'zip' } diff --git a/src/main/java/org/terasology/web/io/GsonMessageBodyHandler.java b/src/main/java/org/terasology/web/io/GsonMessageBodyHandler.java deleted file mode 100644 index 95f0657..0000000 --- a/src/main/java/org/terasology/web/io/GsonMessageBodyHandler.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.terasology.web.io; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.nio.charset.StandardCharsets; - -import javax.ws.rs.Consumes; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyReader; -import javax.ws.rs.ext.MessageBodyWriter; -import javax.ws.rs.ext.Provider; - -import org.terasology.naming.Name; -import org.terasology.naming.Version; -import org.terasology.naming.gson.NameTypeAdapter; -import org.terasology.naming.gson.VersionTypeAdapter; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -/** - * Adapted from - * http://eclipsesource.com/blogs/2012/11/02/integrating-gson-into-a-jax-rs-based-application/ - */ -@Provider -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public final class GsonMessageBodyHandler implements MessageBodyWriter, MessageBodyReader { - - private static final Gson GSON = new GsonBuilder() - .setPrettyPrinting() - .registerTypeAdapter(Version.class, new VersionTypeAdapter()) - .registerTypeAdapter(Name.class, new NameTypeAdapter()) - .create(); - - @Override - public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return true; - } - - @Override - public Object readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, - MultivaluedMap httpHeaders, InputStream entityStream) throws IOException { - - try (Reader streamReader = new InputStreamReader(entityStream, StandardCharsets.UTF_8)) { - - Type jsonType; - if (type.equals(genericType)) { - jsonType = type; - } else { - jsonType = genericType; - } - - return GSON.fromJson(streamReader, jsonType); - } - } - - @Override - public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return true; - } - - @Override - public long getSize(Object object, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return -1; - } - - @Override - public void writeTo(Object object, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, - MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException { - - try (Writer writer = new OutputStreamWriter(entityStream, StandardCharsets.UTF_8)) { - - Type jsonType; - if (type.equals(genericType)) { - jsonType = type; - } else { - jsonType = genericType; - } - - GSON.toJson(object, jsonType, writer); - } - } -} diff --git a/src/test/java/org/terasology/master/JooqDbTest.java b/src/test/java/org/terasology/master/JooqDbTest.java index 99142ed..1c91712 100644 --- a/src/test/java/org/terasology/master/JooqDbTest.java +++ b/src/test/java/org/terasology/master/JooqDbTest.java @@ -17,7 +17,7 @@ package org.terasology.master; import io.micronaut.test.annotation.MicronautTest; -import org.junit.Assert; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.terasology.web.db.DataBase; @@ -39,10 +39,10 @@ void testConnection() throws Exception { Map data = db.readAll(tableName).get(0); - Assert.assertEquals("myName", data.get("name")); - Assert.assertEquals("Tester", data.get("owner")); - Assert.assertEquals(25000, data.get("port")); - Assert.assertEquals("localhost", data.get("address")); - Assert.assertEquals(true, data.get("active")); + Assertions.assertEquals("myName", data.get("name")); + Assertions.assertEquals("Tester", data.get("owner")); + Assertions.assertEquals(25000, data.get("port")); + Assertions.assertEquals("localhost", data.get("address")); + Assertions.assertEquals(true, data.get("active")); } } diff --git a/src/test/java/org/terasology/master/ModuleUpdateTest.java b/src/test/java/org/terasology/master/ModuleUpdateTest.java index 378da59..f997689 100644 --- a/src/test/java/org/terasology/master/ModuleUpdateTest.java +++ b/src/test/java/org/terasology/master/ModuleUpdateTest.java @@ -20,6 +20,7 @@ import io.micronaut.core.io.IOUtils; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; +import io.micronaut.http.HttpStatus; import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import org.junit.jupiter.api.Assertions; @@ -28,7 +29,6 @@ import org.terasology.module.ModuleMetadataJsonAdapter; import javax.inject.Inject; -import javax.ws.rs.core.Response.Status; import java.io.*; import java.net.MalformedURLException; import java.net.URL; @@ -54,9 +54,9 @@ void testUpdate() throws MalformedURLException, IOException { // send update notification String classpathFile = "/jenkins/CommonWorld-jenkins-notification.json"; - int responseCode = postNotification("/modules/update", classpathFile); + HttpStatus responseCode = postNotification("/modules/update", classpathFile); - Assertions.assertEquals(Status.OK.getStatusCode(), responseCode); + Assertions.assertEquals(HttpStatus.OK, responseCode); Assertions.assertEquals(1, readJsonList("/modules/list/CommonWorld").size()); Assertions.assertEquals(snapshot012, readJsonList("/modules/list/CommonWorld").get(0)); @@ -64,7 +64,7 @@ void testUpdate() throws MalformedURLException, IOException { // send 2nd update notification responseCode = postNotification("/modules/update", classpathFile); - Assertions.assertEquals(Status.OK.getStatusCode(), responseCode); + Assertions.assertEquals(HttpStatus.OK, responseCode); Assertions.assertEquals(2, readJsonList("/modules/list/CommonWorld").size()); @@ -97,12 +97,12 @@ private List readJsonList(String path) throws IOException { return result; } - private int postNotification(String path, String classpathFile) throws IOException { + private HttpStatus postNotification(String path, String classpathFile) throws IOException { // curl -X POST -d @ --header "Content-Type:application/json" try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(classpathFile)))) { String notificationBody = IOUtils.readText(reader); HttpResponse response = client.toBlocking().exchange(HttpRequest.POST(path, notificationBody)); - return response.code(); + return response.getStatus(); } } } diff --git a/src/test/java/org/terasology/master/ServerHtmlContentTest.java b/src/test/java/org/terasology/master/ServerHtmlContentTest.java index edfc3fd..a042e3a 100644 --- a/src/test/java/org/terasology/master/ServerHtmlContentTest.java +++ b/src/test/java/org/terasology/master/ServerHtmlContentTest.java @@ -22,7 +22,7 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; -import org.junit.Assert; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import javax.inject.Inject; @@ -43,12 +43,12 @@ public void testShowHtml() { Document doc = Jsoup.parse(response); Element table = doc.getElementById("server-list"); - Assert.assertTrue(table.nodeName().equals("table")); + Assertions.assertTrue(table.nodeName().equals("table")); Element tableBody = table.select("tbody").first(); Element firstRow = tableBody.select("tr").first(); - Assert.assertEquals(firstEntry.getName(), firstRow.getElementsByClass("server-name").first().text()); - Assert.assertEquals(firstEntry.getOwner(), firstRow.getElementsByClass("server-owner").first().text()); - Assert.assertEquals("" + firstEntry.getPort(), firstRow.getElementsByClass("server-port").first().text()); - Assert.assertEquals(firstEntry.getAddress(), firstRow.getElementsByClass("server-address").first().text()); + Assertions.assertEquals(firstEntry.getName(), firstRow.getElementsByClass("server-name").first().text()); + Assertions.assertEquals(firstEntry.getOwner(), firstRow.getElementsByClass("server-owner").first().text()); + Assertions.assertEquals("" + firstEntry.getPort(), firstRow.getElementsByClass("server-port").first().text()); + Assertions.assertEquals(firstEntry.getAddress(), firstRow.getElementsByClass("server-address").first().text()); } } From 07130d1f28eef2c196ba0bd1cc9ebb14d1e5957a Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 14:47:17 +0300 Subject: [PATCH 05/20] migration(micronauts): move packages to more common places. --- .../AboutController.java | 2 +- .../ModuleController.java} | 19 +++--------- .../ServerController.java} | 15 ++++----- .../{ => model}/artifactory/ArtifactInfo.java | 2 +- .../artifactory/ArtifactRepository.java | 2 +- .../artifactory/ArtifactoryArtifactInfo.java | 6 ++-- .../artifactory/ArtifactoryItem.java | 2 +- .../artifactory/ArtifactoryModule.java | 2 +- .../artifactory/ArtifactoryRepo.java | 31 ++++++------------- .../web/model/{ => module}/RemoteModule.java | 10 +++--- .../web/model/{ => server}/Result.java | 2 +- .../web/model/{ => server}/ServerEntry.java | 2 +- .../{servlet => model/web}/ServerForm.java | 2 +- .../web/{db => services/api}/DataBase.java | 6 ++-- .../api}/GeoLocationService.java | 4 ++- .../api}/MetadataExtractor.java | 6 ++-- .../api}/ModuleListModel.java | 2 +- .../api}/ServerListModel.java | 5 ++- .../impl}/ModuleListModelImpl.java | 9 ++++-- .../impl}/ServerListModelImpl.java | 7 +++-- .../impl}/ZipExtractor.java | 3 +- .../{ => services/impl}/db/JooqDatabase.java | 7 +++-- .../{ => services/impl}/geo/GeoLocation.java | 2 +- .../impl}/geo/dbip/DbIpQueryResponse.java | 4 +-- .../impl}/geo/dbip/DbIpRestWrapper.java | 2 +- .../geo/dbip/GeoLocationServiceDbIp.java | 6 ++-- .../java/org/terasology/master/BaseTests.java | 12 +++---- .../master/ClasspathArtifactInfo.java | 10 +++--- .../org/terasology/master/JooqDbTest.java | 2 +- .../terasology/master/ServerJsonListTest.java | 2 +- .../master/services/DummyArtifactRepo.java | 4 +-- .../master/services/DummyExtractor.java | 4 +-- .../services/DummyGeoLocationService.java | 4 +-- 33 files changed, 95 insertions(+), 103 deletions(-) rename src/main/java/org/terasology/web/{servlet => controllers}/AboutController.java (97%) rename src/main/java/org/terasology/web/{servlet/ModuleServlet.java => controllers/ModuleController.java} (94%) rename src/main/java/org/terasology/web/{servlet/ServerServlet.java => controllers/ServerController.java} (95%) rename src/main/java/org/terasology/web/{ => model}/artifactory/ArtifactInfo.java (94%) rename src/main/java/org/terasology/web/{ => model}/artifactory/ArtifactRepository.java (95%) rename src/main/java/org/terasology/web/{ => model}/artifactory/ArtifactoryArtifactInfo.java (97%) rename src/main/java/org/terasology/web/{ => model}/artifactory/ArtifactoryItem.java (97%) rename src/main/java/org/terasology/web/{ => model}/artifactory/ArtifactoryModule.java (94%) rename src/main/java/org/terasology/web/{ => model}/artifactory/ArtifactoryRepo.java (94%) rename src/main/java/org/terasology/web/model/{ => module}/RemoteModule.java (96%) rename src/main/java/org/terasology/web/model/{ => server}/Result.java (96%) rename src/main/java/org/terasology/web/model/{ => server}/ServerEntry.java (98%) rename src/main/java/org/terasology/web/{servlet => model/web}/ServerForm.java (96%) rename src/main/java/org/terasology/web/{db => services/api}/DataBase.java (95%) rename src/main/java/org/terasology/web/{geo => services/api}/GeoLocationService.java (88%) rename src/main/java/org/terasology/web/{model => services/api}/MetadataExtractor.java (95%) rename src/main/java/org/terasology/web/{model => services/api}/ModuleListModel.java (96%) rename src/main/java/org/terasology/web/{model => services/api}/ServerListModel.java (87%) rename src/main/java/org/terasology/web/{model => services/impl}/ModuleListModelImpl.java (96%) rename src/main/java/org/terasology/web/{model => services/impl}/ServerListModelImpl.java (96%) rename src/main/java/org/terasology/web/{model => services/impl}/ZipExtractor.java (95%) rename src/main/java/org/terasology/web/{ => services/impl}/db/JooqDatabase.java (97%) rename src/main/java/org/terasology/web/{ => services/impl}/geo/GeoLocation.java (94%) rename src/main/java/org/terasology/web/{ => services/impl}/geo/dbip/DbIpQueryResponse.java (94%) rename src/main/java/org/terasology/web/{ => services/impl}/geo/dbip/DbIpRestWrapper.java (94%) rename src/main/java/org/terasology/web/{ => services/impl}/geo/dbip/GeoLocationServiceDbIp.java (91%) diff --git a/src/main/java/org/terasology/web/servlet/AboutController.java b/src/main/java/org/terasology/web/controllers/AboutController.java similarity index 97% rename from src/main/java/org/terasology/web/servlet/AboutController.java rename to src/main/java/org/terasology/web/controllers/AboutController.java index 26e2204..738a677 100644 --- a/src/main/java/org/terasology/web/servlet/AboutController.java +++ b/src/main/java/org/terasology/web/controllers/AboutController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.servlet; +package org.terasology.web.controllers; import io.micronaut.core.util.CollectionUtils; import io.micronaut.http.HttpResponse; diff --git a/src/main/java/org/terasology/web/servlet/ModuleServlet.java b/src/main/java/org/terasology/web/controllers/ModuleController.java similarity index 94% rename from src/main/java/org/terasology/web/servlet/ModuleServlet.java rename to src/main/java/org/terasology/web/controllers/ModuleController.java index 8d111c7..8103f19 100644 --- a/src/main/java/org/terasology/web/servlet/ModuleServlet.java +++ b/src/main/java/org/terasology/web/controllers/ModuleController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.servlet; +package org.terasology.web.controllers; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Multimap; @@ -24,9 +24,7 @@ import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.*; -import io.micronaut.http.server.util.HttpHostResolver; import io.micronaut.views.View; -import io.micronaut.web.router.RouteBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.module.Module; @@ -36,8 +34,8 @@ import org.terasology.naming.Name; import org.terasology.naming.Version; import org.terasology.naming.exception.VersionParseException; -import org.terasology.web.model.ModuleListModel; import org.terasology.web.model.jenkins.Job; +import org.terasology.web.services.api.ModuleListModel; import org.terasology.web.version.VersionInfo; import java.io.IOException; @@ -49,9 +47,9 @@ * TODO Type description */ @Controller("/modules/") -public class ModuleServlet { +public class ModuleController { - private static final Logger logger = LoggerFactory.getLogger(ModuleServlet.class); + private static final Logger logger = LoggerFactory.getLogger(ModuleController.class); private final ModuleListModel model; @@ -62,17 +60,10 @@ public class ModuleServlet { */ private final Comparator versionComparator = (m1, m2) -> m2.getVersion().compareTo(m1.getVersion()); - private final HttpHostResolver httpHostResolver; - private final RouteBuilder.UriNamingStrategy uriNamingStrategy; - - public ModuleServlet( - HttpHostResolver httpHostResolver, - RouteBuilder.UriNamingStrategy uriNamingStrategy, + public ModuleController( ModuleListModel model ) { this.model = model; - this.httpHostResolver = httpHostResolver; - this.uriNamingStrategy = uriNamingStrategy; this.metadataWriter = new ModuleMetadataJsonAdapter(); for (RemoteModuleExtension ext : RemoteModuleExtension.values()) { metadataWriter.registerExtension(ext.getKey(), ext.getValueType()); diff --git a/src/main/java/org/terasology/web/servlet/ServerServlet.java b/src/main/java/org/terasology/web/controllers/ServerController.java similarity index 95% rename from src/main/java/org/terasology/web/servlet/ServerServlet.java rename to src/main/java/org/terasology/web/controllers/ServerController.java index 67df871..bd734d5 100644 --- a/src/main/java/org/terasology/web/servlet/ServerServlet.java +++ b/src/main/java/org/terasology/web/controllers/ServerController.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.servlet; +package org.terasology.web.controllers; import com.google.common.collect.ImmutableMap; import io.micronaut.http.HttpResponse; @@ -23,9 +23,10 @@ import io.micronaut.views.View; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.web.model.Result; -import org.terasology.web.model.ServerEntry; -import org.terasology.web.model.ServerListModel; +import org.terasology.web.model.server.Result; +import org.terasology.web.model.server.ServerEntry; +import org.terasology.web.model.web.ServerForm; +import org.terasology.web.services.api.ServerListModel; import org.terasology.web.version.VersionInfo; import java.io.IOException; @@ -38,13 +39,13 @@ * */ @Controller("/servers/") -public class ServerServlet { +public class ServerController { - private static final Logger logger = LoggerFactory.getLogger(ServerServlet.class); + private static final Logger logger = LoggerFactory.getLogger(ServerController.class); private ServerListModel model; - public ServerServlet(ServerListModel model) { + public ServerController(ServerListModel model) { this.model = model; } diff --git a/src/main/java/org/terasology/web/artifactory/ArtifactInfo.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactInfo.java similarity index 94% rename from src/main/java/org/terasology/web/artifactory/ArtifactInfo.java rename to src/main/java/org/terasology/web/model/artifactory/ArtifactInfo.java index c9a6c54..28c83bf 100644 --- a/src/main/java/org/terasology/web/artifactory/ArtifactInfo.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.artifactory; +package org.terasology.web.model.artifactory; import java.net.URL; import java.util.Date; diff --git a/src/main/java/org/terasology/web/artifactory/ArtifactRepository.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactRepository.java similarity index 95% rename from src/main/java/org/terasology/web/artifactory/ArtifactRepository.java rename to src/main/java/org/terasology/web/model/artifactory/ArtifactRepository.java index 300181e..d07f45a 100644 --- a/src/main/java/org/terasology/web/artifactory/ArtifactRepository.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactRepository.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.artifactory; +package org.terasology.web.model.artifactory; import java.io.IOException; import java.util.Collection; diff --git a/src/main/java/org/terasology/web/artifactory/ArtifactoryArtifactInfo.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryArtifactInfo.java similarity index 97% rename from src/main/java/org/terasology/web/artifactory/ArtifactoryArtifactInfo.java rename to src/main/java/org/terasology/web/model/artifactory/ArtifactoryArtifactInfo.java index 545a18c..4479579 100644 --- a/src/main/java/org/terasology/web/artifactory/ArtifactoryArtifactInfo.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryArtifactInfo.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.terasology.web.artifactory; +package org.terasology.web.model.artifactory; + +import com.google.common.base.Preconditions; import java.net.URL; import java.util.Date; -import com.google.common.base.Preconditions; - /** * Describes a module based on its URL in Artifactory. */ diff --git a/src/main/java/org/terasology/web/artifactory/ArtifactoryItem.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryItem.java similarity index 97% rename from src/main/java/org/terasology/web/artifactory/ArtifactoryItem.java rename to src/main/java/org/terasology/web/model/artifactory/ArtifactoryItem.java index 26bba41..f5de85c 100644 --- a/src/main/java/org/terasology/web/artifactory/ArtifactoryItem.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryItem.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.artifactory; +package org.terasology.web.model.artifactory; import java.net.URL; import java.util.Date; diff --git a/src/main/java/org/terasology/web/artifactory/ArtifactoryModule.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryModule.java similarity index 94% rename from src/main/java/org/terasology/web/artifactory/ArtifactoryModule.java rename to src/main/java/org/terasology/web/model/artifactory/ArtifactoryModule.java index d82a7a9..1c0b37a 100644 --- a/src/main/java/org/terasology/web/artifactory/ArtifactoryModule.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryModule.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.artifactory; +package org.terasology.web.model.artifactory; import java.util.Date; import java.util.List; diff --git a/src/main/java/org/terasology/web/artifactory/ArtifactoryRepo.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryRepo.java similarity index 94% rename from src/main/java/org/terasology/web/artifactory/ArtifactoryRepo.java rename to src/main/java/org/terasology/web/model/artifactory/ArtifactoryRepo.java index 2b39a3a..32d68d6 100644 --- a/src/main/java/org/terasology/web/artifactory/ArtifactoryRepo.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryRepo.java @@ -14,32 +14,19 @@ * limitations under the License. */ -package org.terasology.web.artifactory; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.Writer; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +package org.terasology.web.model.artifactory; import com.google.common.io.Files; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.*; /** * Implements {@link ArtifactRepository} for Artifactory. diff --git a/src/main/java/org/terasology/web/model/RemoteModule.java b/src/main/java/org/terasology/web/model/module/RemoteModule.java similarity index 96% rename from src/main/java/org/terasology/web/model/RemoteModule.java rename to src/main/java/org/terasology/web/model/module/RemoteModule.java index 755ca50..420c911 100644 --- a/src/main/java/org/terasology/web/model/RemoteModule.java +++ b/src/main/java/org/terasology/web/model/module/RemoteModule.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.terasology.web.model; - -import java.net.URL; -import java.util.Collections; +package org.terasology.web.model.module; +import com.google.common.collect.ImmutableList; import org.terasology.module.BaseModule; import org.terasology.module.ModuleMetadata; -import com.google.common.collect.ImmutableList; + +import java.net.URL; +import java.util.Collections; /** * TODO Type description diff --git a/src/main/java/org/terasology/web/model/Result.java b/src/main/java/org/terasology/web/model/server/Result.java similarity index 96% rename from src/main/java/org/terasology/web/model/Result.java rename to src/main/java/org/terasology/web/model/server/Result.java index 150a29f..191ed30 100644 --- a/src/main/java/org/terasology/web/model/Result.java +++ b/src/main/java/org/terasology/web/model/server/Result.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.model; +package org.terasology.web.model.server; public final class Result { diff --git a/src/main/java/org/terasology/web/model/ServerEntry.java b/src/main/java/org/terasology/web/model/server/ServerEntry.java similarity index 98% rename from src/main/java/org/terasology/web/model/ServerEntry.java rename to src/main/java/org/terasology/web/model/server/ServerEntry.java index d66fa6e..42ea91a 100644 --- a/src/main/java/org/terasology/web/model/ServerEntry.java +++ b/src/main/java/org/terasology/web/model/server/ServerEntry.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.model; +package org.terasology.web.model.server; import java.util.Objects; diff --git a/src/main/java/org/terasology/web/servlet/ServerForm.java b/src/main/java/org/terasology/web/model/web/ServerForm.java similarity index 96% rename from src/main/java/org/terasology/web/servlet/ServerForm.java rename to src/main/java/org/terasology/web/model/web/ServerForm.java index 1ea0aad..2365fe5 100644 --- a/src/main/java/org/terasology/web/servlet/ServerForm.java +++ b/src/main/java/org/terasology/web/model/web/ServerForm.java @@ -1,4 +1,4 @@ -package org.terasology.web.servlet; +package org.terasology.web.model.web; /** * Pojo for Server add/edit form. diff --git a/src/main/java/org/terasology/web/db/DataBase.java b/src/main/java/org/terasology/web/services/api/DataBase.java similarity index 95% rename from src/main/java/org/terasology/web/db/DataBase.java rename to src/main/java/org/terasology/web/services/api/DataBase.java index 998e8a0..59ff218 100644 --- a/src/main/java/org/terasology/web/db/DataBase.java +++ b/src/main/java/org/terasology/web/services/api/DataBase.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package org.terasology.web.db; +package org.terasology.web.services.api; + +import org.terasology.web.model.server.ServerEntry; import java.sql.SQLException; import java.util.List; import java.util.Map; -import org.terasology.web.model.ServerEntry; - /** * Describes a permanent data storage. */ diff --git a/src/main/java/org/terasology/web/geo/GeoLocationService.java b/src/main/java/org/terasology/web/services/api/GeoLocationService.java similarity index 88% rename from src/main/java/org/terasology/web/geo/GeoLocationService.java rename to src/main/java/org/terasology/web/services/api/GeoLocationService.java index 7fe7947..60ccb00 100644 --- a/src/main/java/org/terasology/web/geo/GeoLocationService.java +++ b/src/main/java/org/terasology/web/services/api/GeoLocationService.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package org.terasology.web.geo; +package org.terasology.web.services.api; + +import org.terasology.web.services.impl.geo.GeoLocation; import java.io.IOException; diff --git a/src/main/java/org/terasology/web/model/MetadataExtractor.java b/src/main/java/org/terasology/web/services/api/MetadataExtractor.java similarity index 95% rename from src/main/java/org/terasology/web/model/MetadataExtractor.java rename to src/main/java/org/terasology/web/services/api/MetadataExtractor.java index 838c9ff..210a0b1 100644 --- a/src/main/java/org/terasology/web/model/MetadataExtractor.java +++ b/src/main/java/org/terasology/web/services/api/MetadataExtractor.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.terasology.web.model; +package org.terasology.web.services.api; + +import org.terasology.module.ModuleMetadata; import java.io.IOException; import java.net.URL; -import org.terasology.module.ModuleMetadata; - public interface MetadataExtractor { /** diff --git a/src/main/java/org/terasology/web/model/ModuleListModel.java b/src/main/java/org/terasology/web/services/api/ModuleListModel.java similarity index 96% rename from src/main/java/org/terasology/web/model/ModuleListModel.java rename to src/main/java/org/terasology/web/services/api/ModuleListModel.java index c9196be..f56df1f 100644 --- a/src/main/java/org/terasology/web/model/ModuleListModel.java +++ b/src/main/java/org/terasology/web/services/api/ModuleListModel.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.model; +package org.terasology.web.services.api; import org.terasology.module.Module; import org.terasology.naming.Name; diff --git a/src/main/java/org/terasology/web/model/ServerListModel.java b/src/main/java/org/terasology/web/services/api/ServerListModel.java similarity index 87% rename from src/main/java/org/terasology/web/model/ServerListModel.java rename to src/main/java/org/terasology/web/services/api/ServerListModel.java index 6120ea0..85a5c2e 100644 --- a/src/main/java/org/terasology/web/model/ServerListModel.java +++ b/src/main/java/org/terasology/web/services/api/ServerListModel.java @@ -14,7 +14,10 @@ * limitations under the License. */ -package org.terasology.web.model; +package org.terasology.web.services.api; + +import org.terasology.web.model.server.Result; +import org.terasology.web.model.server.ServerEntry; import java.io.IOException; import java.util.List; diff --git a/src/main/java/org/terasology/web/model/ModuleListModelImpl.java b/src/main/java/org/terasology/web/services/impl/ModuleListModelImpl.java similarity index 96% rename from src/main/java/org/terasology/web/model/ModuleListModelImpl.java rename to src/main/java/org/terasology/web/services/impl/ModuleListModelImpl.java index 2185df8..d22ea43 100644 --- a/src/main/java/org/terasology/web/model/ModuleListModelImpl.java +++ b/src/main/java/org/terasology/web/services/impl/ModuleListModelImpl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.model; +package org.terasology.web.services.impl; import com.google.common.io.Files; import io.micronaut.context.annotation.Value; @@ -24,8 +24,11 @@ import org.terasology.module.*; import org.terasology.naming.Name; import org.terasology.naming.Version; -import org.terasology.web.artifactory.ArtifactInfo; -import org.terasology.web.artifactory.ArtifactRepository; +import org.terasology.web.model.artifactory.ArtifactInfo; +import org.terasology.web.model.artifactory.ArtifactRepository; +import org.terasology.web.model.module.RemoteModule; +import org.terasology.web.services.api.MetadataExtractor; +import org.terasology.web.services.api.ModuleListModel; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Singleton; diff --git a/src/main/java/org/terasology/web/model/ServerListModelImpl.java b/src/main/java/org/terasology/web/services/impl/ServerListModelImpl.java similarity index 96% rename from src/main/java/org/terasology/web/model/ServerListModelImpl.java rename to src/main/java/org/terasology/web/services/impl/ServerListModelImpl.java index 12f19be..59a7fc5 100644 --- a/src/main/java/org/terasology/web/model/ServerListModelImpl.java +++ b/src/main/java/org/terasology/web/services/impl/ServerListModelImpl.java @@ -14,13 +14,16 @@ * limitations under the License. */ -package org.terasology.web.model; +package org.terasology.web.services.impl; import com.google.common.base.Preconditions; import io.micronaut.context.annotation.Value; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.web.db.DataBase; +import org.terasology.web.model.server.Result; +import org.terasology.web.model.server.ServerEntry; +import org.terasology.web.services.api.DataBase; +import org.terasology.web.services.api.ServerListModel; import javax.inject.Singleton; import java.io.IOException; diff --git a/src/main/java/org/terasology/web/model/ZipExtractor.java b/src/main/java/org/terasology/web/services/impl/ZipExtractor.java similarity index 95% rename from src/main/java/org/terasology/web/model/ZipExtractor.java rename to src/main/java/org/terasology/web/services/impl/ZipExtractor.java index b6cc1da..7259dbd 100644 --- a/src/main/java/org/terasology/web/model/ZipExtractor.java +++ b/src/main/java/org/terasology/web/services/impl/ZipExtractor.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.terasology.web.model; +package org.terasology.web.services.impl; import org.terasology.module.ModuleMetadata; import org.terasology.module.ModuleMetadataJsonAdapter; +import org.terasology.web.services.api.MetadataExtractor; import javax.inject.Singleton; import java.io.*; diff --git a/src/main/java/org/terasology/web/db/JooqDatabase.java b/src/main/java/org/terasology/web/services/impl/db/JooqDatabase.java similarity index 97% rename from src/main/java/org/terasology/web/db/JooqDatabase.java rename to src/main/java/org/terasology/web/services/impl/db/JooqDatabase.java index b2b42a7..55d0081 100644 --- a/src/main/java/org/terasology/web/db/JooqDatabase.java +++ b/src/main/java/org/terasology/web/services/impl/db/JooqDatabase.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.db; +package org.terasology.web.services.impl.db; import org.jooq.Record; import org.jooq.*; @@ -22,8 +22,9 @@ import org.jooq.impl.SQLDataType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.web.geo.GeoLocation; -import org.terasology.web.geo.GeoLocationService; +import org.terasology.web.services.api.DataBase; +import org.terasology.web.services.api.GeoLocationService; +import org.terasology.web.services.impl.geo.GeoLocation; import javax.inject.Singleton; import javax.sql.DataSource; diff --git a/src/main/java/org/terasology/web/geo/GeoLocation.java b/src/main/java/org/terasology/web/services/impl/geo/GeoLocation.java similarity index 94% rename from src/main/java/org/terasology/web/geo/GeoLocation.java rename to src/main/java/org/terasology/web/services/impl/geo/GeoLocation.java index 2731090..1ef2aa6 100644 --- a/src/main/java/org/terasology/web/geo/GeoLocation.java +++ b/src/main/java/org/terasology/web/services/impl/geo/GeoLocation.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.geo; +package org.terasology.web.services.impl.geo; /** * Provides geo-location information diff --git a/src/main/java/org/terasology/web/geo/dbip/DbIpQueryResponse.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpQueryResponse.java similarity index 94% rename from src/main/java/org/terasology/web/geo/dbip/DbIpQueryResponse.java rename to src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpQueryResponse.java index 2fe38fb..24c8c74 100644 --- a/src/main/java/org/terasology/web/geo/dbip/DbIpQueryResponse.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpQueryResponse.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package org.terasology.web.geo.dbip; +package org.terasology.web.services.impl.geo.dbip; -import org.terasology.web.geo.GeoLocation; +import org.terasology.web.services.impl.geo.GeoLocation; /** * An implementation that wraps a response from db-ip.com diff --git a/src/main/java/org/terasology/web/geo/dbip/DbIpRestWrapper.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpRestWrapper.java similarity index 94% rename from src/main/java/org/terasology/web/geo/dbip/DbIpRestWrapper.java rename to src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpRestWrapper.java index bd6861f..72fbc07 100644 --- a/src/main/java/org/terasology/web/geo/dbip/DbIpRestWrapper.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpRestWrapper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.terasology.web.geo.dbip; +package org.terasology.web.services.impl.geo.dbip; import retrofit.http.GET; import retrofit.http.Query; diff --git a/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/GeoLocationServiceDbIp.java similarity index 91% rename from src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java rename to src/main/java/org/terasology/web/services/impl/geo/dbip/GeoLocationServiceDbIp.java index 7528ad6..2828805 100644 --- a/src/main/java/org/terasology/web/geo/dbip/GeoLocationServiceDbIp.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/GeoLocationServiceDbIp.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.terasology.web.geo.dbip; +package org.terasology.web.services.impl.geo.dbip; import io.micronaut.context.annotation.Value; -import org.terasology.web.geo.GeoLocation; -import org.terasology.web.geo.GeoLocationService; +import org.terasology.web.services.api.GeoLocationService; +import org.terasology.web.services.impl.geo.GeoLocation; import retrofit.RestAdapter; import javax.inject.Singleton; diff --git a/src/test/java/org/terasology/master/BaseTests.java b/src/test/java/org/terasology/master/BaseTests.java index 198f4fd..4a85e03 100644 --- a/src/test/java/org/terasology/master/BaseTests.java +++ b/src/test/java/org/terasology/master/BaseTests.java @@ -4,12 +4,12 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.TestInstance; import org.terasology.master.services.DummyArtifactRepo; -import org.terasology.web.artifactory.ArtifactRepository; -import org.terasology.web.db.DataBase; -import org.terasology.web.geo.GeoLocation; -import org.terasology.web.geo.GeoLocationService; -import org.terasology.web.model.ModuleListModelImpl; -import org.terasology.web.model.ServerEntry; +import org.terasology.web.model.artifactory.ArtifactRepository; +import org.terasology.web.model.server.ServerEntry; +import org.terasology.web.services.api.DataBase; +import org.terasology.web.services.api.GeoLocationService; +import org.terasology.web.services.impl.ModuleListModelImpl; +import org.terasology.web.services.impl.geo.GeoLocation; import javax.inject.Inject; import java.io.IOException; diff --git a/src/test/java/org/terasology/master/ClasspathArtifactInfo.java b/src/test/java/org/terasology/master/ClasspathArtifactInfo.java index 1ac0eac..ae3dd18 100644 --- a/src/test/java/org/terasology/master/ClasspathArtifactInfo.java +++ b/src/test/java/org/terasology/master/ClasspathArtifactInfo.java @@ -16,6 +16,11 @@ package org.terasology.master; +import org.terasology.module.ModuleMetadata; +import org.terasology.module.ModuleMetadataJsonAdapter; +import org.terasology.module.RemoteModuleExtension; +import org.terasology.web.model.artifactory.ArtifactInfo; + import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; @@ -23,11 +28,6 @@ import java.nio.charset.StandardCharsets; import java.util.Date; -import org.terasology.module.ModuleMetadata; -import org.terasology.module.ModuleMetadataJsonAdapter; -import org.terasology.module.RemoteModuleExtension; -import org.terasology.web.artifactory.ArtifactInfo; - public class ClasspathArtifactInfo implements ArtifactInfo { private ModuleMetadata meta; diff --git a/src/test/java/org/terasology/master/JooqDbTest.java b/src/test/java/org/terasology/master/JooqDbTest.java index 1c91712..4ae4f34 100644 --- a/src/test/java/org/terasology/master/JooqDbTest.java +++ b/src/test/java/org/terasology/master/JooqDbTest.java @@ -19,7 +19,7 @@ import io.micronaut.test.annotation.MicronautTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.terasology.web.db.DataBase; +import org.terasology.web.services.api.DataBase; import javax.inject.Inject; import java.util.Map; diff --git a/src/test/java/org/terasology/master/ServerJsonListTest.java b/src/test/java/org/terasology/master/ServerJsonListTest.java index 517030a..63e7038 100644 --- a/src/test/java/org/terasology/master/ServerJsonListTest.java +++ b/src/test/java/org/terasology/master/ServerJsonListTest.java @@ -24,7 +24,7 @@ import io.micronaut.http.client.annotation.Client; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.terasology.web.model.ServerEntry; +import org.terasology.web.model.server.ServerEntry; import javax.inject.Inject; import java.io.IOException; diff --git a/src/test/java/org/terasology/master/services/DummyArtifactRepo.java b/src/test/java/org/terasology/master/services/DummyArtifactRepo.java index 1906c9f..f9af576 100644 --- a/src/test/java/org/terasology/master/services/DummyArtifactRepo.java +++ b/src/test/java/org/terasology/master/services/DummyArtifactRepo.java @@ -16,8 +16,8 @@ package org.terasology.master.services; -import org.terasology.web.artifactory.ArtifactInfo; -import org.terasology.web.artifactory.ArtifactRepository; +import org.terasology.web.model.artifactory.ArtifactInfo; +import org.terasology.web.model.artifactory.ArtifactRepository; import java.io.IOException; import java.util.*; diff --git a/src/test/java/org/terasology/master/services/DummyExtractor.java b/src/test/java/org/terasology/master/services/DummyExtractor.java index d9677c6..69ef82f 100644 --- a/src/test/java/org/terasology/master/services/DummyExtractor.java +++ b/src/test/java/org/terasology/master/services/DummyExtractor.java @@ -20,8 +20,8 @@ import org.terasology.module.ModuleMetadata; import org.terasology.module.ModuleMetadataJsonAdapter; import org.terasology.module.RemoteModuleExtension; -import org.terasology.web.model.MetadataExtractor; -import org.terasology.web.model.ZipExtractor; +import org.terasology.web.services.api.MetadataExtractor; +import org.terasology.web.services.impl.ZipExtractor; import javax.inject.Singleton; import java.io.IOException; diff --git a/src/test/java/org/terasology/master/services/DummyGeoLocationService.java b/src/test/java/org/terasology/master/services/DummyGeoLocationService.java index dfff403..f1ff44e 100644 --- a/src/test/java/org/terasology/master/services/DummyGeoLocationService.java +++ b/src/test/java/org/terasology/master/services/DummyGeoLocationService.java @@ -17,8 +17,8 @@ package org.terasology.master.services; import io.micronaut.context.annotation.Primary; -import org.terasology.web.geo.GeoLocation; -import org.terasology.web.geo.GeoLocationService; +import org.terasology.web.services.api.GeoLocationService; +import org.terasology.web.services.impl.geo.GeoLocation; import javax.inject.Singleton; import java.io.IOException; From dcceec03ebd4fc3601c5fbd8e16a9dde6fc648df Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 15:13:32 +0300 Subject: [PATCH 06/20] migration(micronauts): DI Service Renaming --- .../web/controllers/ModuleController.java | 6 ++-- .../web/controllers/ServerController.java | 6 ++-- .../{DataBase.java => DatabaseService.java} | 6 ++-- ...eListModel.java => ModuleListService.java} | 2 +- ...rListModel.java => ServerListService.java} | 2 +- ...elImpl.java => ModuleListServiceImpl.java} | 8 ++--- ...elImpl.java => ServerListServiceImpl.java} | 30 +++++++++---------- ...Database.java => JooqDatabaseService.java} | 8 ++--- ...eDbIp.java => DbIpGeoLocationService.java} | 4 +-- .../java/org/terasology/master/BaseTests.java | 12 ++++---- .../org/terasology/master/JooqDbTest.java | 4 +-- 11 files changed, 44 insertions(+), 44 deletions(-) rename src/main/java/org/terasology/web/services/api/{DataBase.java => DatabaseService.java} (94%) rename src/main/java/org/terasology/web/services/api/{ModuleListModel.java => ModuleListService.java} (96%) rename src/main/java/org/terasology/web/services/api/{ServerListModel.java => ServerListService.java} (96%) rename src/main/java/org/terasology/web/services/impl/{ModuleListModelImpl.java => ModuleListServiceImpl.java} (97%) rename src/main/java/org/terasology/web/services/impl/{ServerListModelImpl.java => ServerListServiceImpl.java} (83%) rename src/main/java/org/terasology/web/services/impl/db/{JooqDatabase.java => JooqDatabaseService.java} (97%) rename src/main/java/org/terasology/web/services/impl/geo/dbip/{GeoLocationServiceDbIp.java => DbIpGeoLocationService.java} (95%) diff --git a/src/main/java/org/terasology/web/controllers/ModuleController.java b/src/main/java/org/terasology/web/controllers/ModuleController.java index 8103f19..dde4bb4 100644 --- a/src/main/java/org/terasology/web/controllers/ModuleController.java +++ b/src/main/java/org/terasology/web/controllers/ModuleController.java @@ -35,7 +35,7 @@ import org.terasology.naming.Version; import org.terasology.naming.exception.VersionParseException; import org.terasology.web.model.jenkins.Job; -import org.terasology.web.services.api.ModuleListModel; +import org.terasology.web.services.api.ModuleListService; import org.terasology.web.version.VersionInfo; import java.io.IOException; @@ -51,7 +51,7 @@ public class ModuleController { private static final Logger logger = LoggerFactory.getLogger(ModuleController.class); - private final ModuleListModel model; + private final ModuleListService model; private final ModuleMetadataJsonAdapter metadataWriter; @@ -61,7 +61,7 @@ public class ModuleController { private final Comparator versionComparator = (m1, m2) -> m2.getVersion().compareTo(m1.getVersion()); public ModuleController( - ModuleListModel model + ModuleListService model ) { this.model = model; this.metadataWriter = new ModuleMetadataJsonAdapter(); diff --git a/src/main/java/org/terasology/web/controllers/ServerController.java b/src/main/java/org/terasology/web/controllers/ServerController.java index bd734d5..8f12d34 100644 --- a/src/main/java/org/terasology/web/controllers/ServerController.java +++ b/src/main/java/org/terasology/web/controllers/ServerController.java @@ -26,7 +26,7 @@ import org.terasology.web.model.server.Result; import org.terasology.web.model.server.ServerEntry; import org.terasology.web.model.web.ServerForm; -import org.terasology.web.services.api.ServerListModel; +import org.terasology.web.services.api.ServerListService; import org.terasology.web.version.VersionInfo; import java.io.IOException; @@ -43,9 +43,9 @@ public class ServerController { private static final Logger logger = LoggerFactory.getLogger(ServerController.class); - private ServerListModel model; + private ServerListService model; - public ServerController(ServerListModel model) { + public ServerController(ServerListService model) { this.model = model; } diff --git a/src/main/java/org/terasology/web/services/api/DataBase.java b/src/main/java/org/terasology/web/services/api/DatabaseService.java similarity index 94% rename from src/main/java/org/terasology/web/services/api/DataBase.java rename to src/main/java/org/terasology/web/services/api/DatabaseService.java index 59ff218..da3f190 100644 --- a/src/main/java/org/terasology/web/services/api/DataBase.java +++ b/src/main/java/org/terasology/web/services/api/DatabaseService.java @@ -25,12 +25,12 @@ /** * Describes a permanent data storage. */ -public interface DataBase { +public interface DatabaseService { /** * @param tableName the name of the DB table - * @param address the server address - * @param port the server port + * @param address the server address + * @param port the server port * @return true if the entry was found and removed, false otherwise * @throws SQLException if the table query fails */ diff --git a/src/main/java/org/terasology/web/services/api/ModuleListModel.java b/src/main/java/org/terasology/web/services/api/ModuleListService.java similarity index 96% rename from src/main/java/org/terasology/web/services/api/ModuleListModel.java rename to src/main/java/org/terasology/web/services/api/ModuleListService.java index f56df1f..76cbcef 100644 --- a/src/main/java/org/terasology/web/services/api/ModuleListModel.java +++ b/src/main/java/org/terasology/web/services/api/ModuleListService.java @@ -26,7 +26,7 @@ /** * Provides a list of modules. */ -public interface ModuleListModel { +public interface ModuleListService { Set getModuleIds(); diff --git a/src/main/java/org/terasology/web/services/api/ServerListModel.java b/src/main/java/org/terasology/web/services/api/ServerListService.java similarity index 96% rename from src/main/java/org/terasology/web/services/api/ServerListModel.java rename to src/main/java/org/terasology/web/services/api/ServerListService.java index 85a5c2e..19c5c27 100644 --- a/src/main/java/org/terasology/web/services/api/ServerListModel.java +++ b/src/main/java/org/terasology/web/services/api/ServerListService.java @@ -22,7 +22,7 @@ import java.io.IOException; import java.util.List; -public interface ServerListModel { +public interface ServerListService { List getServers() throws IOException; diff --git a/src/main/java/org/terasology/web/services/impl/ModuleListModelImpl.java b/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java similarity index 97% rename from src/main/java/org/terasology/web/services/impl/ModuleListModelImpl.java rename to src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java index d22ea43..bd98944 100644 --- a/src/main/java/org/terasology/web/services/impl/ModuleListModelImpl.java +++ b/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java @@ -28,7 +28,7 @@ import org.terasology.web.model.artifactory.ArtifactRepository; import org.terasology.web.model.module.RemoteModule; import org.terasology.web.services.api.MetadataExtractor; -import org.terasology.web.services.api.ModuleListModel; +import org.terasology.web.services.api.ModuleListService; import javax.annotation.concurrent.ThreadSafe; import javax.inject.Singleton; @@ -47,9 +47,9 @@ */ @ThreadSafe @Singleton -public class ModuleListModelImpl implements ModuleListModel { +public class ModuleListServiceImpl implements ModuleListService { - private static final Logger logger = LoggerFactory.getLogger(ModuleListModelImpl.class); + private static final Logger logger = LoggerFactory.getLogger(ModuleListServiceImpl.class); private final ModuleMetadataJsonAdapter metadataAdapter = new ModuleMetadataJsonAdapter(); @@ -63,7 +63,7 @@ public class ModuleListModelImpl implements ModuleListModel { private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); - public ModuleListModelImpl( + public ModuleListServiceImpl( @Value("${meta-server.cache.folder}") Path cacheFolder, MetadataExtractor extractor) { this.cacheFolder = cacheFolder; diff --git a/src/main/java/org/terasology/web/services/impl/ServerListModelImpl.java b/src/main/java/org/terasology/web/services/impl/ServerListServiceImpl.java similarity index 83% rename from src/main/java/org/terasology/web/services/impl/ServerListModelImpl.java rename to src/main/java/org/terasology/web/services/impl/ServerListServiceImpl.java index 59a7fc5..2112b53 100644 --- a/src/main/java/org/terasology/web/services/impl/ServerListModelImpl.java +++ b/src/main/java/org/terasology/web/services/impl/ServerListServiceImpl.java @@ -22,8 +22,8 @@ import org.slf4j.LoggerFactory; import org.terasology.web.model.server.Result; import org.terasology.web.model.server.ServerEntry; -import org.terasology.web.services.api.DataBase; -import org.terasology.web.services.api.ServerListModel; +import org.terasology.web.services.api.DatabaseService; +import org.terasology.web.services.api.ServerListService; import javax.inject.Singleton; import java.io.IOException; @@ -35,32 +35,32 @@ import java.util.Map; @Singleton -public class ServerListModelImpl implements ServerListModel { +public class ServerListServiceImpl implements ServerListService { - private static final Logger logger = LoggerFactory.getLogger(ServerListModelImpl.class); + private static final Logger logger = LoggerFactory.getLogger(ServerListServiceImpl.class); - private final DataBase dataBase; + private final DatabaseService databaseService; private final String tableName; private final String editSecret; - public ServerListModelImpl(DataBase dataBase, - @Value("${meta-server.table.name}") String tableName, - @Value("${meta-server.edit.secret}") String editSecret) throws SQLException { - Preconditions.checkArgument(dataBase != null, "dataSource must not be null"); + public ServerListServiceImpl(DatabaseService databaseService, + @Value("${meta-server.table.name}") String tableName, + @Value("${meta-server.edit.secret}") String editSecret) throws SQLException { + Preconditions.checkArgument(databaseService != null, "dataSource must not be null"); Preconditions.checkArgument(tableName != null, "tableName must not be null"); Preconditions.checkArgument(editSecret != null, "editSecret must not be null"); - this.dataBase = dataBase; + this.databaseService = databaseService; this.tableName = tableName; this.editSecret = editSecret; - dataBase.createTable(tableName); + databaseService.createTable(tableName); } @Override public List getServers() throws IOException { try { - List> data = dataBase.readAll(tableName); + List> data = databaseService.readAll(tableName); List servers = new ArrayList<>(data.size()); for (Map entry : data) { String address = entry.get("address").toString(); @@ -92,7 +92,7 @@ public Result addServer(String name, String address, int port, String owner, boo if (!response.isSuccess()) { return response; } else { - dataBase.insert(tableName, name, address, port, owner, active); + databaseService.insert(tableName, name, address, port, owner, active); return Result.success("Entry added!"); } } catch (Exception e) { @@ -117,7 +117,7 @@ public Result removeServer(String address, int port, String secret) { } try { - if (dataBase.remove(tableName, address, port)) { + if (databaseService.remove(tableName, address, port)) { return Result.success("Entry removed!"); } else { return Result.fail("Entry not found"); @@ -136,7 +136,7 @@ public Result updateServer(String name, String address, int port, String owner, } try { - if (dataBase.update(tableName, name, address, port, owner, active)) { + if (databaseService.update(tableName, name, address, port, owner, active)) { return Result.success("Entry updated!"); } else { return Result.fail("Entry not found"); diff --git a/src/main/java/org/terasology/web/services/impl/db/JooqDatabase.java b/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java similarity index 97% rename from src/main/java/org/terasology/web/services/impl/db/JooqDatabase.java rename to src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java index 55d0081..81e6a55 100644 --- a/src/main/java/org/terasology/web/services/impl/db/JooqDatabase.java +++ b/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java @@ -22,7 +22,7 @@ import org.jooq.impl.SQLDataType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.web.services.api.DataBase; +import org.terasology.web.services.api.DatabaseService; import org.terasology.web.services.api.GeoLocationService; import org.terasology.web.services.impl.geo.GeoLocation; @@ -39,9 +39,9 @@ * */ @Singleton -public final class JooqDatabase implements DataBase { +public final class JooqDatabaseService implements DatabaseService { - private static final Logger logger = LoggerFactory.getLogger(JooqDatabase.class); + private static final Logger logger = LoggerFactory.getLogger(JooqDatabaseService.class); private final DataSource ds; @@ -51,7 +51,7 @@ public final class JooqDatabase implements DataBase { * @param ds the datasource * @param geoService the geo-location service */ - public JooqDatabase(DataSource ds, GeoLocationService geoService) { + public JooqDatabaseService(DataSource ds, GeoLocationService geoService) { this.geoService = geoService; this.ds = ds; } diff --git a/src/main/java/org/terasology/web/services/impl/geo/dbip/GeoLocationServiceDbIp.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java similarity index 95% rename from src/main/java/org/terasology/web/services/impl/geo/dbip/GeoLocationServiceDbIp.java rename to src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java index 2828805..76aee3a 100644 --- a/src/main/java/org/terasology/web/services/impl/geo/dbip/GeoLocationServiceDbIp.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java @@ -30,11 +30,11 @@ * Requires a system environment variable "DBIP_API_KEY" with a valid API key. */ @Singleton -public class GeoLocationServiceDbIp implements GeoLocationService { +public class DbIpGeoLocationService implements GeoLocationService { private final String apiKey; - public GeoLocationServiceDbIp( + public DbIpGeoLocationService( @Value("meta-server.dbip.api.key") String apiKey ) { this.apiKey = apiKey; diff --git a/src/test/java/org/terasology/master/BaseTests.java b/src/test/java/org/terasology/master/BaseTests.java index 4a85e03..1426942 100644 --- a/src/test/java/org/terasology/master/BaseTests.java +++ b/src/test/java/org/terasology/master/BaseTests.java @@ -6,9 +6,9 @@ import org.terasology.master.services.DummyArtifactRepo; import org.terasology.web.model.artifactory.ArtifactRepository; import org.terasology.web.model.server.ServerEntry; -import org.terasology.web.services.api.DataBase; +import org.terasology.web.services.api.DatabaseService; import org.terasology.web.services.api.GeoLocationService; -import org.terasology.web.services.impl.ModuleListModelImpl; +import org.terasology.web.services.impl.ModuleListServiceImpl; import org.terasology.web.services.impl.geo.GeoLocation; import javax.inject.Inject; @@ -22,9 +22,9 @@ public class BaseTests { private static final String SERVER_TABLE = "servers"; protected ServerEntry firstEntry; @Inject - ModuleListModelImpl moduleListModel; + ModuleListServiceImpl moduleListModel; @Inject - DataBase dataBase; + DatabaseService databaseService; @Inject GeoLocationService geoService; @@ -50,7 +50,7 @@ void setupModules() throws IOException, SQLException { @BeforeAll void setupDatabase() throws IOException, SQLException { - dataBase.createTable(SERVER_TABLE); + databaseService.createTable(SERVER_TABLE); GeoLocation geo = geoService.resolve("localhost"); firstEntry = new ServerEntry("localhost", 25000); firstEntry.setName("myName"); @@ -58,6 +58,6 @@ void setupDatabase() throws IOException, SQLException { firstEntry.setCountry(geo.getCountry()); firstEntry.setStateprov(geo.getStateOrProvince()); firstEntry.setCity(geo.getCity()); - dataBase.insert(SERVER_TABLE, firstEntry); + databaseService.insert(SERVER_TABLE, firstEntry); } } diff --git a/src/test/java/org/terasology/master/JooqDbTest.java b/src/test/java/org/terasology/master/JooqDbTest.java index 4ae4f34..18237a2 100644 --- a/src/test/java/org/terasology/master/JooqDbTest.java +++ b/src/test/java/org/terasology/master/JooqDbTest.java @@ -19,7 +19,7 @@ import io.micronaut.test.annotation.MicronautTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.terasology.web.services.api.DataBase; +import org.terasology.web.services.api.DatabaseService; import javax.inject.Inject; import java.util.Map; @@ -28,7 +28,7 @@ class JooqDbTest { @Inject - DataBase db; + DatabaseService db; @Test void testConnection() throws Exception { From 5d8e5dfa0867789b8f32339278f0efa03ae6463e Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 15:47:05 +0300 Subject: [PATCH 07/20] migration(micronauts): remove retrofit. prefer micronaut's client --- build.gradle | 3 --- .../impl/geo/dbip/DbIpGeoLocationService.java | 13 ++++++------- .../web/services/impl/geo/dbip/DbIpRestWrapper.java | 9 +++++---- .../org/terasology/master/ServerJsonListTest.java | 7 +++++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index cac5199..863c824 100644 --- a/build.gradle +++ b/build.gradle @@ -75,9 +75,6 @@ dependencies { implementation 'com.google.guava:guava:18.0' - //Service like rest client. - implementation 'com.squareup.retrofit:retrofit:1.9.0' - //// Tests testAnnotationProcessor(enforcedPlatform("io.micronaut:micronaut-bom:$micronautVersion")) testAnnotationProcessor("io.micronaut:micronaut-inject-java") diff --git a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java index 76aee3a..9a6840a 100644 --- a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java @@ -19,8 +19,8 @@ import io.micronaut.context.annotation.Value; import org.terasology.web.services.api.GeoLocationService; import org.terasology.web.services.impl.geo.GeoLocation; -import retrofit.RestAdapter; +import javax.inject.Inject; import javax.inject.Singleton; import java.io.IOException; import java.net.InetAddress; @@ -34,23 +34,22 @@ public class DbIpGeoLocationService implements GeoLocationService { private final String apiKey; + @Inject + DbIpRestWrapper dbIpRestWrapper; + public DbIpGeoLocationService( - @Value("meta-server.dbip.api.key") String apiKey + @Value("${meta-server.dbip.api.key}") String apiKey ) { this.apiKey = apiKey; } @Override public GeoLocation resolve(String hostnameOrIp) throws IOException { - String url = "http://api.db-ip.com/"; - - RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(url).build(); - DbIpRestWrapper service = restAdapter.create(DbIpRestWrapper.class); InetAddress inet = InetAddress.getByName(hostnameOrIp); String ipAddress = inet.getHostAddress(); - DbIpQueryResponse response = service.getGeoLocation(ipAddress, apiKey); + DbIpQueryResponse response = dbIpRestWrapper.getGeoLocation(ipAddress, apiKey); if (response.isSuccess()) { return response; } else { diff --git a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpRestWrapper.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpRestWrapper.java index 72fbc07..234c856 100644 --- a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpRestWrapper.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpRestWrapper.java @@ -16,14 +16,15 @@ package org.terasology.web.services.impl.geo.dbip; -import retrofit.http.GET; -import retrofit.http.Query; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.client.annotation.Client; /** * Maps the db-ip.com REST-ful API to a Java class. */ +@Client("http://api.db-ip.com/") public interface DbIpRestWrapper { - @GET("/addrinfo") - DbIpQueryResponse getGeoLocation(@Query("addr") String ipAddress, @Query("api_key") String apiKey); + @Get("/addrinfo?addr={ipAddress}&api_key={apiKey}") + DbIpQueryResponse getGeoLocation(String ipAddress, String apiKey); } diff --git a/src/test/java/org/terasology/master/ServerJsonListTest.java b/src/test/java/org/terasology/master/ServerJsonListTest.java index 63e7038..c50b3d4 100644 --- a/src/test/java/org/terasology/master/ServerJsonListTest.java +++ b/src/test/java/org/terasology/master/ServerJsonListTest.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.terasology.web.model.server.ServerEntry; +import org.terasology.web.services.impl.geo.dbip.DbIpGeoLocationService; import javax.inject.Inject; import java.io.IOException; @@ -45,9 +46,11 @@ class ServerJsonListTest extends BaseTests { @Client("/") HttpClient client; - @Test - void testJson() { + @Inject + DbIpGeoLocationService dbIpGeoLocationService; + @Test + void testJson() throws IOException { @SuppressWarnings("serial") Type entryListType = new TypeToken>() { /**/ }.getType(); From e91071d249ce65910ae945de0a9c6d7215671e0f Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 15:48:45 +0300 Subject: [PATCH 08/20] migration(micronauts): remove data for postgres --- src/main/resources/application.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 0aa78fb..e642a40 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,12 +6,11 @@ micronaut: base: paths: - "classpath:static" + datasources: default: url: jdbc:postgresql://localhost:5432/postgres driverClassName: org.postgresql.Driver - username: postgres - password: '' meta-server: cache.folder: "./cache" From f67c4e018f511b4e5d77cb15b8eb243fb36ae184 Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 16:31:03 +0300 Subject: [PATCH 09/20] migration(micronauts): add test property for tests. --- src/main/resources/application-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 3a2da3f..5afc320 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -7,3 +7,4 @@ datasources: meta-server: edit.secret: "foo" + dbip.api.key: "bar" From cdd5d23bb45b261fcce15e15f2ec91322fa2120c Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 17:02:12 +0300 Subject: [PATCH 10/20] migration(micronauts): export Module api to separate controller --- .../web/controllers/AboutController.java | 2 +- .../web/controllers/ModuleController.java | 123 +-------------- .../controllers/api/ApiModuleController.java | 145 ++++++++++++++++++ .../org/terasology/master/ModuleShowTest.java | 1 - 4 files changed, 150 insertions(+), 121 deletions(-) create mode 100644 src/main/java/org/terasology/web/controllers/api/ApiModuleController.java diff --git a/src/main/java/org/terasology/web/controllers/AboutController.java b/src/main/java/org/terasology/web/controllers/AboutController.java index 738a677..ed03a27 100644 --- a/src/main/java/org/terasology/web/controllers/AboutController.java +++ b/src/main/java/org/terasology/web/controllers/AboutController.java @@ -30,7 +30,7 @@ /** * Show the about html page. */ -@Controller() +@Controller public class AboutController { private static final Logger logger = LoggerFactory.getLogger(AboutController.class); diff --git a/src/main/java/org/terasology/web/controllers/ModuleController.java b/src/main/java/org/terasology/web/controllers/ModuleController.java index dde4bb4..96d1561 100644 --- a/src/main/java/org/terasology/web/controllers/ModuleController.java +++ b/src/main/java/org/terasology/web/controllers/ModuleController.java @@ -19,11 +19,13 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Multimap; import com.google.common.collect.TreeMultimap; -import com.google.gson.stream.JsonWriter; import io.micronaut.http.HttpRequest; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; -import io.micronaut.http.annotation.*; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.PathVariable; +import io.micronaut.http.annotation.Produces; import io.micronaut.views.View; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,12 +36,9 @@ import org.terasology.naming.Name; import org.terasology.naming.Version; import org.terasology.naming.exception.VersionParseException; -import org.terasology.web.model.jenkins.Job; import org.terasology.web.services.api.ModuleListService; import org.terasology.web.version.VersionInfo; -import java.io.IOException; -import java.io.StringWriter; import java.net.URI; import java.util.*; @@ -70,30 +69,6 @@ public ModuleController( } } - @Get("list") - @Produces(MediaType.APPLICATION_JSON) - public HttpResponse list() { - logger.info("Requested module list as json"); - StringWriter response = new StringWriter(); - List sortedModuleIds = new ArrayList<>(model.getModuleIds()); - sortedModuleIds.sort(null); - try (JsonWriter writer = new JsonWriter(response)) { - writer.beginArray(); - writer.setIndent(" "); // enable pretty printing - for (Name name : sortedModuleIds) { - for (Module module : model.getModuleVersions(name)) { - ModuleMetadata meta = module.getMetadata(); - metadataWriter.write(meta, writer); - } - } - writer.endArray(); - } catch (IOException e) { - logger.error("Cannot create module list", e); - return HttpResponse.serverError(); - } - return HttpResponse.ok(response.toString()); - } - @Get("show") @View("module-list") @Produces(MediaType.TEXT_HTML) @@ -116,51 +91,6 @@ public HttpResponse show() { return HttpResponse.ok(dataModel); } - @Get("list/latest") - @Produces(MediaType.APPLICATION_JSON) - public HttpResponse listLatest() { - logger.info("Requested lastest info as json"); - StringWriter response = new StringWriter(); - List sortedModuleIds = new ArrayList<>(model.getModuleIds()); - sortedModuleIds.sort(null); - try (JsonWriter writer = new JsonWriter(response)) { - writer.beginArray(); - writer.setIndent(" "); // enable pretty printing - for (Name name : sortedModuleIds) { - Module module = model.getLatestModuleVersion(name); - ModuleMetadata meta = module.getMetadata(); - metadataWriter.write(meta, writer); - } - writer.endArray(); - } catch (IOException e) { - logger.error("Cannot create module list", e); - return HttpResponse.serverError(); - } - return HttpResponse.ok(response.toString()); - } - - @Get("list/{module}") - @Produces(MediaType.APPLICATION_JSON) - public HttpResponse listModule(@PathVariable("module") String moduleName) { - logger.info("Requested module versions as json"); - - Name name = new Name(moduleName); - StringWriter response = new StringWriter(); - try (JsonWriter writer = new JsonWriter(response)) { - writer.beginArray(); - writer.setIndent(" "); // enable pretty printing - for (Module module : model.getModuleVersions(name)) { - ModuleMetadata meta = module.getMetadata(); - metadataWriter.write(meta, writer); - } - writer.endArray(); - } catch (IOException e) { - logger.error("Cannot create module list", e); - return HttpResponse.serverError(); - } - return HttpResponse.ok(response.toString()); - } - @Get("show/{module}") @View("module-list") @Produces(MediaType.TEXT_HTML) @@ -198,29 +128,6 @@ public HttpResponse listModuleLatest(HttpRequest httpRequest, @PathVariable("mod return HttpResponse.temporaryRedirect(redirect); } - @Get("list/{module}/{version}") - @Produces(MediaType.APPLICATION_JSON) - public HttpResponse listModuleVersion(@PathVariable("module") String moduleName, @PathVariable("version") String versionStr) { - logger.info("Requested single module info as json"); - - try { - Version version = new Version(versionStr); - Module module = model.getModule(new Name(moduleName), version); - if (module == null) { - return HttpResponse.notFound(); - } - - ModuleMetadata meta = module.getMetadata(); - StringWriter response = new StringWriter(); - - metadataWriter.write(meta, response); - return HttpResponse.ok(response.toString()); - } catch (VersionParseException e) { - logger.warn("Invalid version for module '{}' specified: {}", moduleName, versionStr); - return HttpResponse.notFound(); - } - } - @Get("show/{module}/latest") @Produces(MediaType.TEXT_HTML) public HttpResponse showModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { @@ -270,26 +177,4 @@ public HttpResponse showModuleVersion(@PathVariable("module") String module, @Pa } } - @Post("update") - @Consumes(MediaType.APPLICATION_JSON) - public HttpResponse updateModulePost(Job jobState) { - String job = jobState.getName(); - - logger.info("Requested module update for {}", job); - - model.updateModule(new Name(job)); - - return HttpResponse.ok(); - } - - @Post("update-all") - @Consumes(MediaType.APPLICATION_JSON) - public HttpResponse updateAllModulesPost() { - - logger.info("Requested complete module update"); - - new Thread(model::updateAllModules).start(); - - return HttpResponse.ok(); - } } diff --git a/src/main/java/org/terasology/web/controllers/api/ApiModuleController.java b/src/main/java/org/terasology/web/controllers/api/ApiModuleController.java new file mode 100644 index 0000000..363f296 --- /dev/null +++ b/src/main/java/org/terasology/web/controllers/api/ApiModuleController.java @@ -0,0 +1,145 @@ +package org.terasology.web.controllers.api; + +import com.google.gson.stream.JsonWriter; +import io.micronaut.http.HttpResponse; +import io.micronaut.http.MediaType; +import io.micronaut.http.annotation.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.terasology.module.Module; +import org.terasology.module.ModuleMetadata; +import org.terasology.module.ModuleMetadataJsonAdapter; +import org.terasology.module.RemoteModuleExtension; +import org.terasology.naming.Name; +import org.terasology.naming.Version; +import org.terasology.naming.exception.VersionParseException; +import org.terasology.web.model.jenkins.Job; +import org.terasology.web.services.api.ModuleListService; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.List; +import java.util.stream.Collectors; + +@Controller("/modules/") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class ApiModuleController { + + private static final Logger logger = LoggerFactory.getLogger(ApiModuleController.class); + + private final ModuleListService model; + + private final ModuleMetadataJsonAdapter metadataWriter; + + public ApiModuleController( + ModuleListService model + ) { + this.model = model; + this.metadataWriter = new ModuleMetadataJsonAdapter(); + for (RemoteModuleExtension ext : RemoteModuleExtension.values()) { + metadataWriter.registerExtension(ext.getKey(), ext.getValueType()); + } + } + + @Get("list") + public HttpResponse list() { + logger.info("Requested module list as json"); + + List sortedModuleMetadatas = model.getModuleIds() + .stream() + .sorted() + .flatMap(name -> model.getModuleVersions(name).stream()) + .map(Module::getMetadata) + .collect(Collectors.toList()); + + return createResponse(sortedModuleMetadatas); + } + + + @Get("list/latest") + public HttpResponse listLatest() { + logger.info("Requested lastest info as json"); + + List sortedModuleMetadatas = model.getModuleIds() + .stream() + .sorted() + .map(model::getLatestModuleVersion) + .map(Module::getMetadata) + .collect(Collectors.toList()); + + return createResponse(sortedModuleMetadatas); + } + + @Get("list/{module}") + public HttpResponse listModule(@PathVariable("module") String moduleName) { + logger.info("Requested module versions as json"); + + Name name = new Name(moduleName); + List moduleMetadatas = model.getModuleVersions(name) + .stream().map(Module::getMetadata) + .collect(Collectors.toList()); + + return createResponse(moduleMetadatas); + } + + @Get("list/{module}/{version}") + public HttpResponse listModuleVersion(@PathVariable("module") String moduleName, @PathVariable("version") String versionStr) { + logger.info("Requested single module info as json"); + try { + Version version = new Version(versionStr); + Module module = model.getModule(new Name(moduleName), version); + if (module != null) { + ModuleMetadata meta = module.getMetadata(); + StringWriter response = new StringWriter(); + + metadataWriter.write(meta, response); + return HttpResponse.ok(response.toString()); + + } else { + return HttpResponse.notFound(); + } + + } catch (VersionParseException e) { + logger.warn("Invalid version for module '{}' specified: {}", moduleName, versionStr); + return HttpResponse.notFound(); + } + } + + @Post("update") + public HttpResponse updateModulePost(Job jobState) { + String job = jobState.getName(); + + logger.info("Requested module update for {}", job); + + model.updateModule(new Name(job)); + + return HttpResponse.ok(); + } + + @Post("update-all") + public HttpResponse updateAllModulesPost() { + + logger.info("Requested complete module update"); + + new Thread(model::updateAllModules).start(); + + return HttpResponse.ok(); + } + + private HttpResponse createResponse(List sortedModuleMetadatas) { + StringWriter response = new StringWriter(); + try (JsonWriter writer = new JsonWriter(response)) { + writer.beginArray(); + writer.setIndent(" "); // enable pretty printing + for (ModuleMetadata meta : sortedModuleMetadatas) { + metadataWriter.write(meta, writer); + } + writer.endArray(); + } catch (IOException e) { + logger.error("Cannot create module list", e); + return HttpResponse.serverError(); + } + return HttpResponse.ok(response.toString()); + } +} diff --git a/src/test/java/org/terasology/master/ModuleShowTest.java b/src/test/java/org/terasology/master/ModuleShowTest.java index 4af2b71..41cb847 100644 --- a/src/test/java/org/terasology/master/ModuleShowTest.java +++ b/src/test/java/org/terasology/master/ModuleShowTest.java @@ -41,7 +41,6 @@ class ModuleShowTest extends BaseTests { @Client("/") HttpClient client; - @Test void testNonExistingModuleVersion() { HttpClientResponseException exception = Assertions.assertThrows(HttpClientResponseException.class, From 77ae6c1d2d12a1fd64053fba153fdeeff6a0354b Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 17:31:46 +0300 Subject: [PATCH 11/20] migration(micronauts): export Server api to separate controller ServerController use `ModelAndView` now for Either page returns --- .../web/controllers/ModuleController.java | 7 +-- .../web/controllers/ServerController.java | 52 ++++++++----------- .../controllers/api/ApiServerController.java | 38 ++++++++++++++ 3 files changed, 60 insertions(+), 37 deletions(-) create mode 100644 src/main/java/org/terasology/web/controllers/api/ApiServerController.java diff --git a/src/main/java/org/terasology/web/controllers/ModuleController.java b/src/main/java/org/terasology/web/controllers/ModuleController.java index 96d1561..0a5a762 100644 --- a/src/main/java/org/terasology/web/controllers/ModuleController.java +++ b/src/main/java/org/terasology/web/controllers/ModuleController.java @@ -46,6 +46,7 @@ * TODO Type description */ @Controller("/modules/") +@Produces(MediaType.TEXT_HTML) public class ModuleController { private static final Logger logger = LoggerFactory.getLogger(ModuleController.class); @@ -71,7 +72,6 @@ public ModuleController( @Get("show") @View("module-list") - @Produces(MediaType.TEXT_HTML) public HttpResponse show() { logger.info("Requested module list as HTML"); @@ -93,7 +93,6 @@ public HttpResponse show() { @Get("show/{module}") @View("module-list") - @Produces(MediaType.TEXT_HTML) public HttpResponse showModule(@PathVariable("module") String module) { logger.info("Requested module versions as HTML"); @@ -113,7 +112,6 @@ public HttpResponse showModule(@PathVariable("module") String module) { } @Get("list/{module}/latest") - @Produces(MediaType.TEXT_HTML) public HttpResponse listModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { URI uri = httpRequest.getUri(); logger.info("Requested lastest module info as HTML"); @@ -129,7 +127,6 @@ public HttpResponse listModuleLatest(HttpRequest httpRequest, @PathVariable("mod } @Get("show/{module}/latest") - @Produces(MediaType.TEXT_HTML) public HttpResponse showModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { URI uriInfo = httpRequest.getUri(); logger.info("Requested lastest module info as HTML"); @@ -146,7 +143,6 @@ public HttpResponse showModuleLatest(HttpRequest httpRequest, @PathVariable("mod @Get("show/{module}/{version}") @View("module-info") - @Produces(MediaType.TEXT_HTML) public HttpResponse showModuleVersion(@PathVariable("module") String module, @PathVariable("version") String version) { logger.info("Requested module info as HTML"); @@ -176,5 +172,4 @@ public HttpResponse showModuleVersion(@PathVariable("module") String module, @Pa return HttpResponse.notFound(); } } - } diff --git a/src/main/java/org/terasology/web/controllers/ServerController.java b/src/main/java/org/terasology/web/controllers/ServerController.java index 8f12d34..8746867 100644 --- a/src/main/java/org/terasology/web/controllers/ServerController.java +++ b/src/main/java/org/terasology/web/controllers/ServerController.java @@ -20,6 +20,7 @@ import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.*; +import io.micronaut.views.ModelAndView; import io.micronaut.views.View; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +31,6 @@ import org.terasology.web.version.VersionInfo; import java.io.IOException; -import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; import java.util.List; @@ -39,6 +39,7 @@ * */ @Controller("/servers/") +@Produces(MediaType.TEXT_HTML) public class ServerController { private static final Logger logger = LoggerFactory.getLogger(ServerController.class); @@ -51,7 +52,6 @@ public ServerController(ServerListService model) { @Get("show") @View("server-list") - @Produces(MediaType.TEXT_HTML) public HttpResponse show() { logger.info("Requested server list as HTML"); ImmutableMap dataModel = ImmutableMap.builder() @@ -63,7 +63,6 @@ public HttpResponse show() { @Get("add") @View("add") - @Produces(MediaType.TEXT_HTML) public HttpResponse add() { logger.info("Requested add as HTML"); ImmutableMap dataModel = ImmutableMap.builder() @@ -79,7 +78,6 @@ public HttpResponse add() { @Get("edit") @View("edit") - @Produces(MediaType.TEXT_HTML) public HttpResponse edit(@QueryValue(value = "index", defaultValue = "-1") int index) throws IOException { List servers = model.getServers(); @@ -101,22 +99,8 @@ public HttpResponse edit(@QueryValue(value = "index", defaultValue = "-1") int i return HttpResponse.ok(dataModel); } - @Get("list") - @Produces(MediaType.APPLICATION_JSON) - public Object list() { - logger.info("Requested server list"); - try { - return model.getServers(); - } catch (IOException e) { - logger.error("Could not connect to database", e); - return Collections.emptyList(); - } - } - @Post("add") - @View("add") - @Produces(MediaType.TEXT_HTML) - public HttpResponse add(@Body ServerForm serverForm) throws URISyntaxException { + public ModelAndView add(@Body ServerForm serverForm) throws URISyntaxException { boolean active = "on".equals(serverForm.getActiveOn()); logger.info("Requested addition: name: {}, address: {}, port:{}, owner:{}, active:{}", serverForm.getName(), serverForm.getAddress(), serverForm.getPort(), serverForm.getOwner(), active); @@ -129,7 +113,7 @@ public HttpResponse add(@Body ServerForm serverForm) throws URISyntaxException { .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return HttpResponse.redirect(new URI("list")); + return new ModelAndView("list", dataModel); } else { ImmutableMap dataModel = ImmutableMap.builder() .put("name", serverForm.getName()) @@ -140,14 +124,12 @@ public HttpResponse add(@Body ServerForm serverForm) throws URISyntaxException { .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return HttpResponse.ok(dataModel); + return new ModelAndView("add", dataModel); } } @Post("remove") - @View("edit") - @Produces(MediaType.TEXT_HTML) - public HttpResponse remove(@Body ServerForm serverForm) throws URISyntaxException { + public ModelAndView remove(@Body ServerForm serverForm) throws URISyntaxException { boolean active = "on".equals(serverForm.getActiveOn()); Result response = model.removeServer(serverForm.getAddress(), serverForm.getPort(), serverForm.getSecret()); @@ -157,7 +139,7 @@ public HttpResponse remove(@Body ServerForm serverForm) throws URISyntaxExceptio .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return HttpResponse.redirect(new URI("list")); + return new ModelAndView("list", dataModel); } else { ImmutableMap dataModel = ImmutableMap.builder() .put("name", serverForm.getName()) @@ -168,14 +150,12 @@ public HttpResponse remove(@Body ServerForm serverForm) throws URISyntaxExceptio .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return HttpResponse.ok(dataModel); + return new ModelAndView("edit", dataModel); } } @Post("update") - @View("edit") - @Produces(MediaType.TEXT_HTML) - public HttpResponse update(@Body ServerForm serverForm) throws URISyntaxException { + public ModelAndView update(@Body ServerForm serverForm) throws URISyntaxException { boolean active = "on".equals(serverForm.getActiveOn()); Result response = model.updateServer(serverForm.getName(), serverForm.getAddress(), serverForm.getPort(), serverForm.getOwner(), active, serverForm.getActiveOn()); @@ -185,7 +165,7 @@ public HttpResponse update(@Body ServerForm serverForm) throws URISyntaxExceptio .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return HttpResponse.redirect(new URI("list")); + return new ModelAndView("list", dataModel); } else { ImmutableMap dataModel = ImmutableMap.builder() .put("name", serverForm.getName()) @@ -196,7 +176,17 @@ public HttpResponse update(@Body ServerForm serverForm) throws URISyntaxExceptio .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return HttpResponse.ok(dataModel); + return new ModelAndView("edit", dataModel); + } + } + + private List list() { + logger.info("Requested server list"); + try { + return model.getServers(); + } catch (IOException e) { + logger.error("Could not connect to database", e); + return Collections.emptyList(); } } } diff --git a/src/main/java/org/terasology/web/controllers/api/ApiServerController.java b/src/main/java/org/terasology/web/controllers/api/ApiServerController.java new file mode 100644 index 0000000..276de7c --- /dev/null +++ b/src/main/java/org/terasology/web/controllers/api/ApiServerController.java @@ -0,0 +1,38 @@ +package org.terasology.web.controllers.api; + +import io.micronaut.http.MediaType; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Produces; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.terasology.web.model.server.ServerEntry; +import org.terasology.web.services.api.ServerListService; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +@Controller("/servers/") +@Produces(MediaType.APPLICATION_JSON) +public class ApiServerController { + + private static final Logger logger = LoggerFactory.getLogger(ApiServerController.class); + + private ServerListService model; + + public ApiServerController(ServerListService model) { + this.model = model; + } + + @Get("list") + public List list() { + logger.info("Requested server list"); + try { + return model.getServers(); + } catch (IOException e) { + logger.error("Could not connect to database", e); + return Collections.emptyList(); + } + } +} From b972042235867e37e22469e798b2162d8bbb6a59 Mon Sep 17 00:00:00 2001 From: DarkWeird Date: Fri, 25 Sep 2020 17:58:29 +0300 Subject: [PATCH 12/20] chore(micronauts): Fix CheckStyle, Idea's and Sonar's issues --- src/main/java/org/terasology/Application.java | 7 +- .../module/RemoteModuleExtension.java | 18 +- .../web/controllers/ModuleController.java | 35 +- .../web/controllers/ServerController.java | 71 +- .../controllers/api/ApiModuleController.java | 24 +- .../controllers/api/ApiServerController.java | 5 +- .../model/artifactory/ArtifactRepository.java | 10 +- .../artifactory/ArtifactoryArtifactInfo.java | 2 +- .../model/artifactory/ArtifactoryItem.java | 4 +- .../model/artifactory/ArtifactoryRepo.java | 74 +- .../terasology/web/model/jenkins/Build.java | 14 +- .../web/model/server/ServerEntry.java | 23 +- .../terasology/web/model/web/ServerForm.java | 3 + .../web/services/api/DatabaseService.java | 2 +- .../services/impl/ModuleListServiceImpl.java | 41 +- .../web/services/impl/ZipExtractor.java | 25 +- .../services/impl/db/JooqDatabaseService.java | 98 +-- .../impl/geo/dbip/DbIpGeoLocationService.java | 6 +- .../impl/geo/dbip/DbIpQueryResponse.java | 2 + src/main/resources/logback.xml | 4 +- .../fonts/glyphicons-halflings-regular.svg | 825 ++++++++++++------ src/main/resources/static/index.html | 6 +- .../java/org/terasology/master/BaseTests.java | 3 +- .../master/ClasspathArtifactInfo.java | 6 +- .../terasology/master/ModuleUpdateTest.java | 11 +- .../org/terasology/master/ValidatorTests.java | 2 +- .../master/services/DummyArtifactRepo.java | 13 +- .../CommonWorld-jenkins-notification.json | 42 +- src/test/resources/logback-test.xml | 4 +- 29 files changed, 818 insertions(+), 562 deletions(-) diff --git a/src/main/java/org/terasology/Application.java b/src/main/java/org/terasology/Application.java index 71b3e75..4efde02 100644 --- a/src/main/java/org/terasology/Application.java +++ b/src/main/java/org/terasology/Application.java @@ -1,8 +1,13 @@ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + package org.terasology; import io.micronaut.runtime.Micronaut; -public class Application { +public final class Application { + private Application() { + } public static void main(String[] args) { Micronaut.run(Application.class, args); diff --git a/src/main/java/org/terasology/module/RemoteModuleExtension.java b/src/main/java/org/terasology/module/RemoteModuleExtension.java index cf98526..f2ba97a 100644 --- a/src/main/java/org/terasology/module/RemoteModuleExtension.java +++ b/src/main/java/org/terasology/module/RemoteModuleExtension.java @@ -31,19 +31,11 @@ public enum RemoteModuleExtension { private final String key; private final Class valueType; - private RemoteModuleExtension(String key, Class valueType) { + RemoteModuleExtension(String key, Class valueType) { this.key = key; this.valueType = valueType; } - public String getKey() { - return key; - } - - public Class getValueType() { - return valueType; - } - public static URL getDownloadUrl(ModuleMetadata meta) { return meta.getExtension(DOWNLOAD_URL.getKey(), URL.class); } @@ -67,4 +59,12 @@ public static long getArtifactSize(ModuleMetadata meta) { public static void setArtifactSize(ModuleMetadata meta, long size) { meta.setExtension(ARTIFACT_SIZE.getKey(), size); } + + public String getKey() { + return key; + } + + public Class getValueType() { + return valueType; + } } diff --git a/src/main/java/org/terasology/web/controllers/ModuleController.java b/src/main/java/org/terasology/web/controllers/ModuleController.java index 0a5a762..9e3a7f5 100644 --- a/src/main/java/org/terasology/web/controllers/ModuleController.java +++ b/src/main/java/org/terasology/web/controllers/ModuleController.java @@ -1,18 +1,5 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 package org.terasology.web.controllers; @@ -40,7 +27,13 @@ import org.terasology.web.version.VersionInfo; import java.net.URI; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * TODO Type description @@ -72,7 +65,7 @@ public ModuleController( @Get("show") @View("module-list") - public HttpResponse show() { + public HttpResponse> show() { logger.info("Requested module list as HTML"); Set names = model.getModuleIds(); @@ -93,7 +86,7 @@ public HttpResponse show() { @Get("show/{module}") @View("module-list") - public HttpResponse showModule(@PathVariable("module") String module) { + public HttpResponse> showModule(@PathVariable("module") String module) { logger.info("Requested module versions as HTML"); Name name = new Name(module); @@ -112,7 +105,7 @@ public HttpResponse showModule(@PathVariable("module") String module) { } @Get("list/{module}/latest") - public HttpResponse listModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { + public HttpResponse> listModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { URI uri = httpRequest.getUri(); logger.info("Requested lastest module info as HTML"); int pathLen = uri.getPath().length(); @@ -127,7 +120,7 @@ public HttpResponse listModuleLatest(HttpRequest httpRequest, @PathVariable("mod } @Get("show/{module}/latest") - public HttpResponse showModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { + public HttpResponse> showModuleLatest(HttpRequest httpRequest, @PathVariable("module") String module) { URI uriInfo = httpRequest.getUri(); logger.info("Requested lastest module info as HTML"); int pathLen = uriInfo.getPath().length(); @@ -143,7 +136,7 @@ public HttpResponse showModuleLatest(HttpRequest httpRequest, @PathVariable("mod @Get("show/{module}/{version}") @View("module-info") - public HttpResponse showModuleVersion(@PathVariable("module") String module, @PathVariable("version") String version) { + public HttpResponse> showModuleVersion(@PathVariable("module") String module, @PathVariable("version") String version) { logger.info("Requested module info as HTML"); try { diff --git a/src/main/java/org/terasology/web/controllers/ServerController.java b/src/main/java/org/terasology/web/controllers/ServerController.java index 8746867..8f28715 100644 --- a/src/main/java/org/terasology/web/controllers/ServerController.java +++ b/src/main/java/org/terasology/web/controllers/ServerController.java @@ -1,25 +1,17 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 package org.terasology.web.controllers; import com.google.common.collect.ImmutableMap; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; -import io.micronaut.http.annotation.*; +import io.micronaut.http.annotation.Body; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.Post; +import io.micronaut.http.annotation.Produces; +import io.micronaut.http.annotation.QueryValue; import io.micronaut.views.ModelAndView; import io.micronaut.views.View; import org.slf4j.Logger; @@ -31,12 +23,12 @@ import org.terasology.web.version.VersionInfo; import java.io.IOException; -import java.net.URISyntaxException; import java.util.Collections; import java.util.List; +import java.util.Map; /** - * + * Controller which servers WEB for meta-server */ @Controller("/servers/") @Produces(MediaType.TEXT_HTML) @@ -44,7 +36,7 @@ public class ServerController { private static final Logger logger = LoggerFactory.getLogger(ServerController.class); - private ServerListService model; + private final ServerListService model; public ServerController(ServerListService model) { this.model = model; @@ -52,7 +44,7 @@ public ServerController(ServerListService model) { @Get("show") @View("server-list") - public HttpResponse show() { + public HttpResponse> show() { logger.info("Requested server list as HTML"); ImmutableMap dataModel = ImmutableMap.builder() .put("items", list()) @@ -63,7 +55,7 @@ public HttpResponse show() { @Get("add") @View("add") - public HttpResponse add() { + public HttpResponse> add() { logger.info("Requested add as HTML"); ImmutableMap dataModel = ImmutableMap.builder() .put("name", "") @@ -78,7 +70,7 @@ public HttpResponse add() { @Get("edit") @View("edit") - public HttpResponse edit(@QueryValue(value = "index", defaultValue = "-1") int index) throws IOException { + public HttpResponse> edit(@QueryValue(value = "index", defaultValue = "-1") int index) throws IOException { List servers = model.getServers(); if (index < 0 || index >= servers.size()) { @@ -100,12 +92,23 @@ public HttpResponse edit(@QueryValue(value = "index", defaultValue = "-1") int i } @Post("add") - public ModelAndView add(@Body ServerForm serverForm) throws URISyntaxException { + public ModelAndView> add(@Body ServerForm serverForm) { boolean active = "on".equals(serverForm.getActiveOn()); - logger.info("Requested addition: name: {}, address: {}, port:{}, owner:{}, active:{}", serverForm.getName(), serverForm.getAddress(), serverForm.getPort(), serverForm.getOwner(), active); - - Result response = model.addServer(serverForm.getName(), serverForm.getAddress(), serverForm.getPort(), serverForm.getOwner(), active, serverForm.getSecret()); + logger.info("Requested addition: name: {}, address: {}, port:{}, owner:{}, active:{}", + serverForm.getName(), + serverForm.getAddress(), + serverForm.getPort(), + serverForm.getOwner(), + active); + + Result response = model.addServer( + serverForm.getName(), + serverForm.getAddress(), + serverForm.getPort(), + serverForm.getOwner(), + active, + serverForm.getSecret()); if (response.isSuccess()) { ImmutableMap dataModel = ImmutableMap.builder() @@ -113,7 +116,7 @@ public ModelAndView add(@Body ServerForm serverForm) throws URISyntaxException { .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new ModelAndView("list", dataModel); + return new ModelAndView<>("list", dataModel); } else { ImmutableMap dataModel = ImmutableMap.builder() .put("name", serverForm.getName()) @@ -124,12 +127,12 @@ public ModelAndView add(@Body ServerForm serverForm) throws URISyntaxException { .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new ModelAndView("add", dataModel); + return new ModelAndView<>("add", dataModel); } } @Post("remove") - public ModelAndView remove(@Body ServerForm serverForm) throws URISyntaxException { + public ModelAndView> remove(@Body ServerForm serverForm) { boolean active = "on".equals(serverForm.getActiveOn()); Result response = model.removeServer(serverForm.getAddress(), serverForm.getPort(), serverForm.getSecret()); @@ -139,7 +142,7 @@ public ModelAndView remove(@Body ServerForm serverForm) throws URISyntaxExceptio .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new ModelAndView("list", dataModel); + return new ModelAndView<>("list", dataModel); } else { ImmutableMap dataModel = ImmutableMap.builder() .put("name", serverForm.getName()) @@ -150,12 +153,12 @@ public ModelAndView remove(@Body ServerForm serverForm) throws URISyntaxExceptio .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new ModelAndView("edit", dataModel); + return new ModelAndView<>("edit", dataModel); } } @Post("update") - public ModelAndView update(@Body ServerForm serverForm) throws URISyntaxException { + public ModelAndView> update(@Body ServerForm serverForm) { boolean active = "on".equals(serverForm.getActiveOn()); Result response = model.updateServer(serverForm.getName(), serverForm.getAddress(), serverForm.getPort(), serverForm.getOwner(), active, serverForm.getActiveOn()); @@ -165,7 +168,7 @@ public ModelAndView update(@Body ServerForm serverForm) throws URISyntaxExceptio .put("message", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new ModelAndView("list", dataModel); + return new ModelAndView<>("list", dataModel); } else { ImmutableMap dataModel = ImmutableMap.builder() .put("name", serverForm.getName()) @@ -176,7 +179,7 @@ public ModelAndView update(@Body ServerForm serverForm) throws URISyntaxExceptio .put("error", response.getMessage()) .put("version", VersionInfo.getVersion()) .build(); - return new ModelAndView("edit", dataModel); + return new ModelAndView<>("edit", dataModel); } } diff --git a/src/main/java/org/terasology/web/controllers/api/ApiModuleController.java b/src/main/java/org/terasology/web/controllers/api/ApiModuleController.java index 363f296..5e777fd 100644 --- a/src/main/java/org/terasology/web/controllers/api/ApiModuleController.java +++ b/src/main/java/org/terasology/web/controllers/api/ApiModuleController.java @@ -1,9 +1,17 @@ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + package org.terasology.web.controllers.api; import com.google.gson.stream.JsonWriter; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; -import io.micronaut.http.annotation.*; +import io.micronaut.http.annotation.Consumes; +import io.micronaut.http.annotation.Controller; +import io.micronaut.http.annotation.Get; +import io.micronaut.http.annotation.PathVariable; +import io.micronaut.http.annotation.Post; +import io.micronaut.http.annotation.Produces; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.module.Module; @@ -43,7 +51,7 @@ public ApiModuleController( } @Get("list") - public HttpResponse list() { + public HttpResponse list() { logger.info("Requested module list as json"); List sortedModuleMetadatas = model.getModuleIds() @@ -58,7 +66,7 @@ public HttpResponse list() { @Get("list/latest") - public HttpResponse listLatest() { + public HttpResponse listLatest() { logger.info("Requested lastest info as json"); List sortedModuleMetadatas = model.getModuleIds() @@ -72,7 +80,7 @@ public HttpResponse listLatest() { } @Get("list/{module}") - public HttpResponse listModule(@PathVariable("module") String moduleName) { + public HttpResponse listModule(@PathVariable("module") String moduleName) { logger.info("Requested module versions as json"); Name name = new Name(moduleName); @@ -84,7 +92,7 @@ public HttpResponse listModule(@PathVariable("module") String moduleName) { } @Get("list/{module}/{version}") - public HttpResponse listModuleVersion(@PathVariable("module") String moduleName, @PathVariable("version") String versionStr) { + public HttpResponse listModuleVersion(@PathVariable("module") String moduleName, @PathVariable("version") String versionStr) { logger.info("Requested single module info as json"); try { Version version = new Version(versionStr); @@ -107,7 +115,7 @@ public HttpResponse listModuleVersion(@PathVariable("module") String moduleName, } @Post("update") - public HttpResponse updateModulePost(Job jobState) { + public HttpResponse updateModulePost(Job jobState) { String job = jobState.getName(); logger.info("Requested module update for {}", job); @@ -118,7 +126,7 @@ public HttpResponse updateModulePost(Job jobState) { } @Post("update-all") - public HttpResponse updateAllModulesPost() { + public HttpResponse updateAllModulesPost() { logger.info("Requested complete module update"); @@ -127,7 +135,7 @@ public HttpResponse updateAllModulesPost() { return HttpResponse.ok(); } - private HttpResponse createResponse(List sortedModuleMetadatas) { + private HttpResponse createResponse(List sortedModuleMetadatas) { StringWriter response = new StringWriter(); try (JsonWriter writer = new JsonWriter(response)) { writer.beginArray(); diff --git a/src/main/java/org/terasology/web/controllers/api/ApiServerController.java b/src/main/java/org/terasology/web/controllers/api/ApiServerController.java index 276de7c..e6a7ffb 100644 --- a/src/main/java/org/terasology/web/controllers/api/ApiServerController.java +++ b/src/main/java/org/terasology/web/controllers/api/ApiServerController.java @@ -1,3 +1,6 @@ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + package org.terasology.web.controllers.api; import io.micronaut.http.MediaType; @@ -19,7 +22,7 @@ public class ApiServerController { private static final Logger logger = LoggerFactory.getLogger(ApiServerController.class); - private ServerListService model; + private final ServerListService model; public ApiServerController(ServerListService model) { this.model = model; diff --git a/src/main/java/org/terasology/web/model/artifactory/ArtifactRepository.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactRepository.java index d07f45a..c94f96c 100644 --- a/src/main/java/org/terasology/web/model/artifactory/ArtifactRepository.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactRepository.java @@ -21,11 +21,6 @@ public interface ArtifactRepository { - public enum RepoType { - RELEASE, - SNAPSHOT - } - String getName(); RepoType getType(); @@ -35,4 +30,9 @@ public enum RepoType { void updateModule(String moduleName) throws IOException; Collection getModuleArtifacts(String moduleName); + + enum RepoType { + RELEASE, + SNAPSHOT + } } diff --git a/src/main/java/org/terasology/web/model/artifactory/ArtifactoryArtifactInfo.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryArtifactInfo.java index 4479579..547d622 100644 --- a/src/main/java/org/terasology/web/model/artifactory/ArtifactoryArtifactInfo.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryArtifactInfo.java @@ -26,7 +26,7 @@ */ public class ArtifactoryArtifactInfo implements ArtifactInfo { private final String artifact; - private ArtifactoryItem item; + private final ArtifactoryItem item; public ArtifactoryArtifactInfo(ArtifactoryItem item) { Preconditions.checkArgument(item != null); diff --git a/src/main/java/org/terasology/web/model/artifactory/ArtifactoryItem.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryItem.java index f5de85c..c2d1c8a 100644 --- a/src/main/java/org/terasology/web/model/artifactory/ArtifactoryItem.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryItem.java @@ -35,8 +35,8 @@ class ArtifactoryItem { int size; // "14063", static class Entry { - String uri; // "/terasology", - boolean folder; + String uri; // "/terasology", + boolean folder; } } diff --git a/src/main/java/org/terasology/web/model/artifactory/ArtifactoryRepo.java b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryRepo.java index 32d68d6..0353059 100644 --- a/src/main/java/org/terasology/web/model/artifactory/ArtifactoryRepo.java +++ b/src/main/java/org/terasology/web/model/artifactory/ArtifactoryRepo.java @@ -1,18 +1,5 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 package org.terasology.web.model.artifactory; @@ -22,11 +9,23 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.*; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.Writer; import java.net.URL; import java.nio.charset.StandardCharsets; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; /** * Implements {@link ArtifactRepository} for Artifactory. @@ -77,15 +76,26 @@ public static ArtifactoryRepo release(String uri, String repoName, String group, return new ArtifactoryRepo(uri, repoName, group, cacheFolder, RepoType.RELEASE); } + private static ArtifactoryItem readItem(String url) throws IOException { + try (Reader reader = new InputStreamReader(new URL(url).openStream(), StandardCharsets.UTF_8)) { + return GSON.fromJson(reader, ArtifactoryItem.class); + } + } + + private static boolean matches(String uri) { + if (uri.endsWith(".jar")) { + return !uri.endsWith("-sources.jar") && !uri.endsWith("-javadoc.jar"); + } + return false; + } + private ArtifactoryModule loadModuleFromCache(String moduleName) throws IOException { File cacheFile = getCacheFile(moduleName); if (cacheFile.exists()) { try (Reader reader = Files.newReader(cacheFile, StandardCharsets.UTF_8)) { - ArtifactoryModule meta = GSON.fromJson(reader, ArtifactoryModule.class); - return meta; - } - catch (RuntimeException e) { + return GSON.fromJson(reader, ArtifactoryModule.class); + } catch (RuntimeException e) { logger.warn("Could not read {}", cacheFile, e); cacheFile.delete(); } @@ -140,9 +150,9 @@ public void updateModule(String moduleName) throws IOException { } } - logger.info("Updated " + moduleName); + logger.info("Updated {}", moduleName); } else { - logger.debug("No updates for " + moduleName); + logger.debug("No updates for {}", moduleName); } artifactInfo.put(moduleName, module.items); @@ -165,7 +175,7 @@ private Set findArtifacts(String versionUrl) throws IOE String artifactUrl = versionUrl + child3.uri; ArtifactoryItem artifact = readItem(artifactUrl); hits.add(new ArtifactoryArtifactInfo(artifact)); - logger.debug("Added " + artifactUrl); + logger.debug("Added {}", artifactUrl); } } return hits; @@ -175,20 +185,4 @@ private Set findArtifacts(String versionUrl) throws IOE public Collection getModuleArtifacts(String moduleName) { return Collections.unmodifiableCollection(artifactInfo.getOrDefault(moduleName, Collections.emptySet())); } - - private static ArtifactoryItem readItem(String url) throws IOException { - try (Reader reader = new InputStreamReader(new URL(url).openStream(), StandardCharsets.UTF_8)) { - ArtifactoryItem folder = GSON.fromJson(reader, ArtifactoryItem.class); - return folder; - } - } - - private static boolean matches(String uri) { - if (uri.endsWith(".jar")) { - if (!uri.endsWith("-sources.jar") && !uri.endsWith("-javadoc.jar")) { - return true; - } - } - return false; - } } diff --git a/src/main/java/org/terasology/web/model/jenkins/Build.java b/src/main/java/org/terasology/web/model/jenkins/Build.java index 7a32c85..4ba6237 100644 --- a/src/main/java/org/terasology/web/model/jenkins/Build.java +++ b/src/main/java/org/terasology/web/model/jenkins/Build.java @@ -16,17 +16,13 @@ package org.terasology.web.model.jenkins; +import com.google.gson.annotations.SerializedName; + import java.util.HashMap; import java.util.Map; -import com.google.gson.annotations.SerializedName; - public class Build { - public enum Phase { - STARTED, COMPLETED, FINALIZED; - } - @SerializedName("full_url") private String fullUrl; private int number; @@ -83,7 +79,7 @@ public Map getParameters() { } public void setParameters(Map params) { - this.parameters = new HashMap(params); + this.parameters = new HashMap<>(params); } public Map> getArtifacts() { @@ -109,4 +105,8 @@ public StringBuilder getLog() { public void setLog(StringBuilder log) { this.log = log; } + + public enum Phase { + STARTED, COMPLETED, FINALIZED + } } diff --git a/src/main/java/org/terasology/web/model/server/ServerEntry.java b/src/main/java/org/terasology/web/model/server/ServerEntry.java index 42ea91a..220e0e5 100644 --- a/src/main/java/org/terasology/web/model/server/ServerEntry.java +++ b/src/main/java/org/terasology/web/model/server/ServerEntry.java @@ -19,6 +19,7 @@ import java.util.Objects; /** + * Server entry database representation. */ public class ServerEntry { @@ -44,6 +45,10 @@ public String getName() { return name; } + public void setName(String name) { + this.name = name; + } + public String getAddress() { return address; } @@ -84,10 +89,6 @@ public void setCity(String city) { this.city = city; } - public void setName(String name) { - this.name = name; - } - public boolean isActive() { return active; } @@ -120,13 +121,13 @@ public boolean equals(Object obj) { ServerEntry other = (ServerEntry) obj; return Objects.equals(address, other.address) - && Objects.equals(port, other.port) - && Objects.equals(name, other.name) - && Objects.equals(owner, other.owner) - && Objects.equals(city, other.city) - && Objects.equals(stateprov, other.stateprov) - && Objects.equals(country, other.country) - && Objects.equals(active, other.active); + && Objects.equals(port, other.port) + && Objects.equals(name, other.name) + && Objects.equals(owner, other.owner) + && Objects.equals(city, other.city) + && Objects.equals(stateprov, other.stateprov) + && Objects.equals(country, other.country) + && Objects.equals(active, other.active); } } diff --git a/src/main/java/org/terasology/web/model/web/ServerForm.java b/src/main/java/org/terasology/web/model/web/ServerForm.java index 2365fe5..3559f4e 100644 --- a/src/main/java/org/terasology/web/model/web/ServerForm.java +++ b/src/main/java/org/terasology/web/model/web/ServerForm.java @@ -1,3 +1,6 @@ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + package org.terasology.web.model.web; /** diff --git a/src/main/java/org/terasology/web/services/api/DatabaseService.java b/src/main/java/org/terasology/web/services/api/DatabaseService.java index da3f190..e40cb77 100644 --- a/src/main/java/org/terasology/web/services/api/DatabaseService.java +++ b/src/main/java/org/terasology/web/services/api/DatabaseService.java @@ -38,10 +38,10 @@ public interface DatabaseService { /** * Retrieves the contents of a table + * * @param tableName the name of the table in the DB * @return a list of rows * @throws SQLException if the table query fails - * @throws IOException if the connection fails */ List> readAll(String tableName) throws SQLException; diff --git a/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java b/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java index bd98944..f192ef3 100644 --- a/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java +++ b/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java @@ -1,18 +1,5 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 package org.terasology.web.services.impl; @@ -20,8 +7,14 @@ import io.micronaut.context.annotation.Value; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.terasology.module.DependencyResolver; import org.terasology.module.Module; -import org.terasology.module.*; +import org.terasology.module.ModuleMetadata; +import org.terasology.module.ModuleMetadataJsonAdapter; +import org.terasology.module.ModuleRegistry; +import org.terasology.module.RemoteModuleExtension; +import org.terasology.module.ResolutionResult; +import org.terasology.module.TableModuleRegistry; import org.terasology.naming.Name; import org.terasology.naming.Version; import org.terasology.web.model.artifactory.ArtifactInfo; @@ -38,7 +31,13 @@ import java.io.Writer; import java.nio.charset.StandardCharsets; import java.nio.file.Path; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -84,7 +83,7 @@ public void updateAllModules() { for (ArtifactRepository repo : repositories) { for (String moduleName : repo.getModuleNames()) { try { - repo.updateModule(moduleName.toString()); + repo.updateModule(moduleName); updateModule(repo, moduleName); } catch (IOException e) { logger.warn("Could not update module {}", moduleName); @@ -161,7 +160,7 @@ private List retrieveMetadata(ArtifactRepository repository, Pat List result = new ArrayList<>(); - logger.debug("Checking " + moduleName); + logger.debug("Checking {}", moduleName); Set usedCacheFiles = new HashSet<>(); for (ArtifactInfo info : repository.getModuleArtifacts(moduleName)) { @@ -173,7 +172,7 @@ private List retrieveMetadata(ArtifactRepository repository, Pat meta = metadataAdapter.read(reader); } } else { - logger.debug("Downloading " + info.getDownloadUrl()); + logger.debug("Downloading {}", info.getDownloadUrl()); meta = extractor.loadMetaData(info.getDownloadUrl()); RemoteModuleExtension.setDownloadUrl(meta, info.getDownloadUrl()); @@ -192,7 +191,7 @@ private List retrieveMetadata(ArtifactRepository repository, Pat for (String fname : moduleCacheFolder.toFile().list()) { if (fname.endsWith("_info.json") && !usedCacheFiles.contains(fname)) { - logger.info("Would delete " + fname); + logger.info("Would delete {}", fname); } } diff --git a/src/main/java/org/terasology/web/services/impl/ZipExtractor.java b/src/main/java/org/terasology/web/services/impl/ZipExtractor.java index 7259dbd..5feca86 100644 --- a/src/main/java/org/terasology/web/services/impl/ZipExtractor.java +++ b/src/main/java/org/terasology/web/services/impl/ZipExtractor.java @@ -1,18 +1,5 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 package org.terasology.web.services.impl; @@ -21,7 +8,11 @@ import org.terasology.web.services.api.MetadataExtractor; import javax.inject.Singleton; -import java.io.*; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -49,7 +40,7 @@ public ZipExtractor(String... filenames) { @Override public ModuleMetadata loadMetaData(URL url) throws IOException { try (InputStream in = url.openStream(); - ZipInputStream zipStream = new ZipInputStream(in)) { + ZipInputStream zipStream = new ZipInputStream(in)) { ZipEntry entry; while ((entry = zipStream.getNextEntry()) != null) { if (filename.contains(entry.getName())) { diff --git a/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java b/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java index 81e6a55..3466e8e 100644 --- a/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java +++ b/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java @@ -1,23 +1,17 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +// Copyright 2020 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 package org.terasology.web.services.impl.db; +import org.jooq.DSLContext; +import org.jooq.Field; +import org.jooq.InsertSetMoreStep; +import org.jooq.Query; import org.jooq.Record; -import org.jooq.*; +import org.jooq.Result; +import org.jooq.SortField; +import org.jooq.Table; +import org.jooq.UpdateSetMoreStep; import org.jooq.impl.DSL; import org.jooq.impl.SQLDataType; import org.slf4j.Logger; @@ -32,11 +26,15 @@ import java.sql.Connection; import java.sql.SQLException; import java.sql.Timestamp; -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; /** - * + * Jooq Database service implementation. */ @Singleton public final class JooqDatabaseService implements DatabaseService { @@ -48,7 +46,7 @@ public final class JooqDatabaseService implements DatabaseService { private final GeoLocationService geoService; /** - * @param ds the datasource + * @param ds the datasource * @param geoService the geo-location service */ public JooqDatabaseService(DataSource ds, GeoLocationService geoService) { @@ -145,11 +143,11 @@ public boolean insert(String tableName, String name, String address, int port, S Table table = DSL.table(DSL.name(tableName)); InsertSetMoreStep statement = context.insertInto(table) - .set(DSL.field(DSL.name("name")), name) - .set(DSL.field(DSL.name("address")), address) - .set(DSL.field(DSL.name("port")), port) - .set(DSL.field(DSL.name("owner")), owner) - .set(DSL.field(DSL.name("active")), active); + .set(DSL.field(DSL.name("name")), name) + .set(DSL.field(DSL.name("address")), address) + .set(DSL.field(DSL.name("port")), port) + .set(DSL.field(DSL.name("owner")), owner) + .set(DSL.field(DSL.name("active")), active); try { GeoLocation geoLoc = geoService.resolve(address); @@ -158,9 +156,9 @@ public boolean insert(String tableName, String name, String address, int port, S String city = geoLoc.getCity(); statement - .set(DSL.field(DSL.name("country")), country) - .set(DSL.field(DSL.name("stateprov")), stateProv) - .set(DSL.field(DSL.name("city")), city); + .set(DSL.field(DSL.name("country")), country) + .set(DSL.field(DSL.name("stateprov")), stateProv) + .set(DSL.field(DSL.name("city")), city); } catch (IOException e) { logger.error("Could not resolve geo-location for {}", address, e); @@ -175,31 +173,31 @@ public boolean insert(String tableName, String name, String address, int port, S private void createTable(DSLContext context, Table table) { context.createTable(table) - .column("name", SQLDataType.VARCHAR.length(256)) - .column("address", SQLDataType.VARCHAR.length(256).nullable(false)) - .column("port", SQLDataType.INTEGER.nullable(false)) - .column("country", SQLDataType.VARCHAR.length(256)) - .column("stateprov", SQLDataType.VARCHAR.length(256)) - .column("city", SQLDataType.VARCHAR.length(256)) - .column("owner", SQLDataType.VARCHAR.length(256)) - .column("active", SQLDataType.BOOLEAN.nullable(false)) - .column("modtime", SQLDataType.TIMESTAMP) - .execute(); + .column("name", SQLDataType.VARCHAR.length(256)) + .column("address", SQLDataType.VARCHAR.length(256).nullable(false)) + .column("port", SQLDataType.INTEGER.nullable(false)) + .column("country", SQLDataType.VARCHAR.length(256)) + .column("stateprov", SQLDataType.VARCHAR.length(256)) + .column("city", SQLDataType.VARCHAR.length(256)) + .column("owner", SQLDataType.VARCHAR.length(256)) + .column("active", SQLDataType.BOOLEAN.nullable(false)) + .column("modtime", SQLDataType.TIMESTAMP) + .execute(); // set default value for active context.alterTable(table) - .alter(DSL.field(DSL.name("active"), Boolean.class)).defaultValue(Boolean.FALSE) - .execute(); + .alter(DSL.field(DSL.name("active"), Boolean.class)).defaultValue(Boolean.FALSE) + .execute(); // modtime timestamp DEFAULT current_timestamp context.alterTable(table) - .alter(DSL.field(DSL.name("modtime"), Timestamp.class)).defaultValue(DSL.currentTimestamp()) - .execute(); + .alter(DSL.field(DSL.name("modtime"), Timestamp.class)).defaultValue(DSL.currentTimestamp()) + .execute(); // PRIMARY KEY (address, port) context.alterTable(table) - .add(DSL.constraint("primary_key").primaryKey("address", "port")) - .execute(); + .add(DSL.constraint("primary_key").primaryKey("address", "port")) + .execute(); } private Table tableExists(DSLContext context, String tableName) { @@ -219,10 +217,10 @@ public boolean update(String tableName, String name, String address, int port, S Table table = DSL.table(DSL.name(tableName)); UpdateSetMoreStep statement = context.update(table) - .set(DSL.field(DSL.name("name")), name) - .set(DSL.field(DSL.name("owner")), owner) - .set(DSL.field(DSL.name("active")), active) - .set(DSL.field(DSL.name("modtime")), DSL.defaultValue(Timestamp.class)); + .set(DSL.field(DSL.name("name")), name) + .set(DSL.field(DSL.name("owner")), owner) + .set(DSL.field(DSL.name("active")), active) + .set(DSL.field(DSL.name("modtime")), DSL.defaultValue(Timestamp.class)); try { GeoLocation geoLoc = geoService.resolve(address); @@ -231,9 +229,9 @@ public boolean update(String tableName, String name, String address, int port, S String city = geoLoc.getCity(); statement - .set(DSL.field(DSL.name("country")), country) - .set(DSL.field(DSL.name("stateprov")), stateProv) - .set(DSL.field(DSL.name("city")), city); + .set(DSL.field(DSL.name("country")), country) + .set(DSL.field(DSL.name("stateprov")), stateProv) + .set(DSL.field(DSL.name("city")), city); } catch (IOException e) { logger.error("Could not resolve geo-location for {}", address, e); diff --git a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java index 9a6840a..e341a36 100644 --- a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java @@ -20,7 +20,6 @@ import org.terasology.web.services.api.GeoLocationService; import org.terasology.web.services.impl.geo.GeoLocation; -import javax.inject.Inject; import javax.inject.Singleton; import java.io.IOException; import java.net.InetAddress; @@ -34,13 +33,14 @@ public class DbIpGeoLocationService implements GeoLocationService { private final String apiKey; - @Inject - DbIpRestWrapper dbIpRestWrapper; + private final DbIpRestWrapper dbIpRestWrapper; public DbIpGeoLocationService( + DbIpRestWrapper dbIpRestWrapper, @Value("${meta-server.dbip.api.key}") String apiKey ) { this.apiKey = apiKey; + this.dbIpRestWrapper = dbIpRestWrapper; } @Override diff --git a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpQueryResponse.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpQueryResponse.java index 24c8c74..c227c30 100644 --- a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpQueryResponse.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpQueryResponse.java @@ -32,6 +32,7 @@ public class DbIpQueryResponse implements GeoLocation { /** * Success indicates that the geolocation fields are filled. * Failure indicates that the error message is filled. + * * @return true if the query was a success */ public boolean isSuccess() { @@ -40,6 +41,7 @@ public boolean isSuccess() { /** * The error message (available only if {@link #isSuccess()} returns false. + * * @return the error message text as by db-ip.com */ public String getError() { diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 89d8fe5..be119fa 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -21,7 +21,7 @@ - - + + diff --git a/src/main/resources/static/fonts/glyphicons-halflings-regular.svg b/src/main/resources/static/fonts/glyphicons-halflings-regular.svg index 94fb549..2ba280f 100644 --- a/src/main/resources/static/fonts/glyphicons-halflings-regular.svg +++ b/src/main/resources/static/fonts/glyphicons-halflings-regular.svg @@ -1,288 +1,543 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 1c552da..413a86c 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -1,6 +1,6 @@ - - - + + + diff --git a/src/test/java/org/terasology/master/BaseTests.java b/src/test/java/org/terasology/master/BaseTests.java index 1426942..0c2f3eb 100644 --- a/src/test/java/org/terasology/master/BaseTests.java +++ b/src/test/java/org/terasology/master/BaseTests.java @@ -21,6 +21,7 @@ public class BaseTests { private static final String SERVER_TABLE = "servers"; protected ServerEntry firstEntry; + protected DummyArtifactRepo snapshotRepo; @Inject ModuleListServiceImpl moduleListModel; @Inject @@ -28,8 +29,6 @@ public class BaseTests { @Inject GeoLocationService geoService; - protected DummyArtifactRepo snapshotRepo; - @BeforeAll void setupModules() throws IOException, SQLException { DummyArtifactRepo releaseRepo = new DummyArtifactRepo(ArtifactRepository.RepoType.RELEASE); diff --git a/src/test/java/org/terasology/master/ClasspathArtifactInfo.java b/src/test/java/org/terasology/master/ClasspathArtifactInfo.java index ae3dd18..2b29e87 100644 --- a/src/test/java/org/terasology/master/ClasspathArtifactInfo.java +++ b/src/test/java/org/terasology/master/ClasspathArtifactInfo.java @@ -30,9 +30,9 @@ public class ClasspathArtifactInfo implements ArtifactInfo { - private ModuleMetadata meta; - private URL url; - private String artifactName; + private final ModuleMetadata meta; + private final URL url; + private final String artifactName; public ClasspathArtifactInfo(String cpUrl) throws IOException { ModuleMetadataJsonAdapter metadataAdapter = new ModuleMetadataJsonAdapter(); diff --git a/src/test/java/org/terasology/master/ModuleUpdateTest.java b/src/test/java/org/terasology/master/ModuleUpdateTest.java index f997689..5ade2a8 100644 --- a/src/test/java/org/terasology/master/ModuleUpdateTest.java +++ b/src/test/java/org/terasology/master/ModuleUpdateTest.java @@ -29,8 +29,11 @@ import org.terasology.module.ModuleMetadataJsonAdapter; import javax.inject.Inject; -import java.io.*; -import java.net.MalformedURLException; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -45,7 +48,7 @@ class ModuleUpdateTest extends BaseTests { HttpClient client; @Test - void testUpdate() throws MalformedURLException, IOException { + void testUpdate() throws IOException { Assertions.assertEquals(0, readJsonList("/modules/list/CommonWorld").size()); @@ -101,7 +104,7 @@ private HttpStatus postNotification(String path, String classpathFile) throws IO // curl -X POST -d @ --header "Content-Type:application/json" try (BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(classpathFile)))) { String notificationBody = IOUtils.readText(reader); - HttpResponse response = client.toBlocking().exchange(HttpRequest.POST(path, notificationBody)); + HttpResponse response = client.toBlocking().exchange(HttpRequest.POST(path, notificationBody)); return response.getStatus(); } } diff --git a/src/test/java/org/terasology/master/ValidatorTests.java b/src/test/java/org/terasology/master/ValidatorTests.java index fd5c06b..8e3ceeb 100644 --- a/src/test/java/org/terasology/master/ValidatorTests.java +++ b/src/test/java/org/terasology/master/ValidatorTests.java @@ -40,7 +40,7 @@ class ValidatorTests extends BaseTests { private static final Logger logger = LoggerFactory.getLogger(ValidatorTests.class); - private static Validator validator = new ValidatorBuilder().html(); + private static final Validator validator = new ValidatorBuilder().html(); @Inject @Client("/") diff --git a/src/test/java/org/terasology/master/services/DummyArtifactRepo.java b/src/test/java/org/terasology/master/services/DummyArtifactRepo.java index f9af576..74862d4 100644 --- a/src/test/java/org/terasology/master/services/DummyArtifactRepo.java +++ b/src/test/java/org/terasology/master/services/DummyArtifactRepo.java @@ -20,7 +20,11 @@ import org.terasology.web.model.artifactory.ArtifactRepository; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; public class DummyArtifactRepo implements ArtifactRepository { @@ -42,12 +46,7 @@ public RepoType getType() { } public void addArtifact(String moduleName, ArtifactInfo info) { - Collection entry = modules.get(moduleName); - if (entry == null) { - entry = new ArrayList<>(); - modules.put(moduleName, entry); - } - entry.add(info); + modules.computeIfAbsent(moduleName, k -> new ArrayList<>()).add(info); } @Override diff --git a/src/test/resources/jenkins/CommonWorld-jenkins-notification.json b/src/test/resources/jenkins/CommonWorld-jenkins-notification.json index d96609b..916c47e 100644 --- a/src/test/resources/jenkins/CommonWorld-jenkins-notification.json +++ b/src/test/resources/jenkins/CommonWorld-jenkins-notification.json @@ -1,27 +1,27 @@ -{ - "name":"CommonWorld", - "url":"job/CommonWorld/", - "build":{ - "full_url":"http://jenkins.terasology.org/job/CommonWorld/21/", - "number":21, - "phase":"FINALIZED", - "status":"SUCCESS", - "url":"job/CommonWorld/21/", - "scm":{ - "url":"git://github.com/Terasology/CommonWorld.git", - "branch":"origin/master", - "commit":"a2ceff4e416d99c35c14f91c5d74edde0439de3d" +{ + "name": "CommonWorld", + "url": "job/CommonWorld/", + "build": { + "full_url": "http://jenkins.terasology.org/job/CommonWorld/21/", + "number": 21, + "phase": "FINALIZED", + "status": "SUCCESS", + "url": "job/CommonWorld/21/", + "scm": { + "url": "git://github.com/Terasology/CommonWorld.git", + "branch": "origin/master", + "commit": "a2ceff4e416d99c35c14f91c5d74edde0439de3d" }, - "log":"Finished: SUCCESS\n", - "artifacts":{ - "CommonWorld-0.1.3-SNAPSHOT-javadoc.jar":{ - "archive":"http://jenkins.terasology.org/job/CommonWorld/21/artifact/build/libs/CommonWorld-0.1.3-SNAPSHOT-javadoc.jar" + "log": "Finished: SUCCESS\n", + "artifacts": { + "CommonWorld-0.1.3-SNAPSHOT-javadoc.jar": { + "archive": "http://jenkins.terasology.org/job/CommonWorld/21/artifact/build/libs/CommonWorld-0.1.3-SNAPSHOT-javadoc.jar" }, - "CommonWorld-0.1.3-SNAPSHOT-sources.jar":{ - "archive":"http://jenkins.terasology.org/job/CommonWorld/21/artifact/build/libs/CommonWorld-0.1.3-SNAPSHOT-sources.jar" + "CommonWorld-0.1.3-SNAPSHOT-sources.jar": { + "archive": "http://jenkins.terasology.org/job/CommonWorld/21/artifact/build/libs/CommonWorld-0.1.3-SNAPSHOT-sources.jar" }, - "CommonWorld-0.1.3-SNAPSHOT.jar":{ - "archive":"http://jenkins.terasology.org/job/CommonWorld/21/artifact/build/libs/CommonWorld-0.1.3-SNAPSHOT.jar" + "CommonWorld-0.1.3-SNAPSHOT.jar": { + "archive": "http://jenkins.terasology.org/job/CommonWorld/21/artifact/build/libs/CommonWorld-0.1.3-SNAPSHOT.jar" } } } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 070d007..6d7dd62 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -13,7 +13,7 @@ - - + + From c6de7e2b7db93d75fdb285aa1dd2be70408e2a4c Mon Sep 17 00:00:00 2001 From: darkweird Date: Tue, 30 Nov 2021 10:26:22 +0300 Subject: [PATCH 13/20] chore(micronauts): remove Jetty references. change Readme.md --- README.md | 17 ++++++++--------- build.gradle | 4 ---- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index fbe088f..bb0a987 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,19 @@ meta-server ========= -A Jetty-based servlet that serves meta-information about Terasology. +Micronauts web application that serves meta-information about Terasology. It is available for in-game use in JSON format and in HTML format for web browsers. The server is available at **http://meta.terasology.org** -hosted by [@msteiger](http://github.com/msteiger). -The list of online game servers is hosted on a Amazon EC2 PostgreSQL instance (through Heroku credentials). -The server code is mirrored on two backup instances hosted on Heroku: - -https://meta-server.herokuapp.com - -https://meta-server-test.herokuapp.com (a debug DB also hosted on Amazon) - +Features +------------- +* Save and provide information about Terasology modules +* Receive and provide information about Terasology servers (Looking for game) +* Using https://db-ip.com/ for providing additional info about servers. +* Use PostgresDB via Jooq for persistence +* Use Micronauts for core Frameworks Deployment ------------- diff --git a/build.gradle b/build.gradle index 863c824..52b6f06 100644 --- a/build.gradle +++ b/build.gradle @@ -29,10 +29,6 @@ repositories { } } -ext { - jettyVersion = '9.4.6.v20170531' -} - java { sourceCompatibility = JavaVersion.toVersion('11') targetCompatibility = JavaVersion.toVersion('11') From dfa333841fcd0767e840b545d08ec65837a0f65e Mon Sep 17 00:00:00 2001 From: darkweird Date: Tue, 30 Nov 2021 10:48:13 +0300 Subject: [PATCH 14/20] build(micronauts): add possible to runs meta-server with test profile. enrich Dockerfile with build --- Dockerfile | 3 +++ build.gradle | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 63b9bc8..93c9767 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,6 @@ +FROM gradle:6.6.1 +CMD gradle shadowJar + FROM openjdk:14-alpine COPY build/libs/meta-server-*-all.jar meta-server.jar EXPOSE 8080 diff --git a/build.gradle b/build.gradle index 52b6f06..c333f06 100644 --- a/build.gradle +++ b/build.gradle @@ -89,7 +89,7 @@ dependencies { // loggin and database testImplementation 'org.slf4j:slf4j-api:1.7.30' - testImplementation 'com.h2database:h2' + implementation 'com.h2database:h2' // Code analyzers pmd 'net.sourceforge.pmd:pmd-core:6.27.0' From 646c5b7b530a7536ba557b313053fd0527dfa0db Mon Sep 17 00:00:00 2001 From: darkweird Date: Tue, 30 Nov 2021 12:02:40 +0300 Subject: [PATCH 15/20] build(micronauts): fix docker build and provide deploy and local run information --- Dockerfile | 11 +++++---- README.md | 32 +++++++++++++++++++++---- src/main/resources/application-test.yml | 3 +++ src/main/resources/application.yml | 2 ++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 93c9767..ceeed80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,10 @@ -FROM gradle:6.6.1 -CMD gradle shadowJar +FROM gradle:6.6.1-jdk11 as builder +CMD mkdir /build +COPY . /build +WORKDIR /build +RUN gradle shadowJar FROM openjdk:14-alpine -COPY build/libs/meta-server-*-all.jar meta-server.jar -EXPOSE 8080 +COPY --from=builder build/build/libs/meta-server-*-all.jar meta-server.jar +EXPOSE 80 CMD ["java", "-Dcom.sun.management.jmxremote", "-Xmx128m", "-jar", "meta-server.jar"] \ No newline at end of file diff --git a/README.md b/README.md index bb0a987..ecf2f90 100644 --- a/README.md +++ b/README.md @@ -15,15 +15,37 @@ Features * Use PostgresDB via Jooq for persistence * Use Micronauts for core Frameworks +Run locally +------------- +Gradle-way: +1. Clone +2. Go to Project Dir +3. Set environment variable `MICRONAUT_ENVIRONMENTS` to `test` (local h2 database) +4. `./gradlew run` at Linux/Macos or `gradlew run` at Windows +5. found at logs entry like `[main] INFO io.micronaut.runtime.Micronaut - Startup completed in 624ms. Server Running: http://localhost:39195` +6. Go To url described at logs with your browser + +Docker-way: +1. Clone +2. Go To Project Dir +3. Run `docker build . -t test-meta-server` +4. Run `docker run --env "MICRONAUT_ENVIRONMENTS=test" test-meta-server` + Deployment ------------- +Docker: +1. Clone repository +2. Go To project directory +3. `docker build . -t ` +4. `docker push` image whatever you want -Heroku: Clone the repository and push the content to Heroku on branch `master`. Some details must be provided through environment variables: +You can setup what you want with [Micronaut's configs](https://docs.micronaut.io/latest/guide/index.html#config): +Common (ENVIRONMENT_VARIABLES): - DATASOURCE_DEFAULT_URL=postgres://name:pw@host:port/database - SERVER_URL=8080 - META_SERVER_DBIP_API_KEY= - META_SERVER_EDIT_SECRET= + MICRONAUT_SERVER_PORT - port (example - 80) + DATASOURCES_DEFAULT_URL - url to PG database (example - postgres://name:pw@host:port/database + META_SERVER_DBIP_API_KEY= + META_SERVER_EDIT_SECRET= Geo-Location ------------- diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 5afc320..13616f2 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -1,3 +1,6 @@ +micronaut: + server: + port: 8080 datasources: default: url: jdbc:h2:mem:testdb diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e642a40..474c683 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,8 @@ micronaut: application: name: meta-server + server: + port: 80 router: static-resources: base: From 8c361032f0a25b2accd7eea1087ea943c44cd1e3 Mon Sep 17 00:00:00 2001 From: darkweird Date: Tue, 30 Nov 2021 15:04:45 +0300 Subject: [PATCH 16/20] fix(micronauts): fix server/add form data handling --- .../org/terasology/web/controllers/ServerController.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/terasology/web/controllers/ServerController.java b/src/main/java/org/terasology/web/controllers/ServerController.java index 8f28715..93a8efe 100644 --- a/src/main/java/org/terasology/web/controllers/ServerController.java +++ b/src/main/java/org/terasology/web/controllers/ServerController.java @@ -6,12 +6,7 @@ import com.google.common.collect.ImmutableMap; import io.micronaut.http.HttpResponse; import io.micronaut.http.MediaType; -import io.micronaut.http.annotation.Body; -import io.micronaut.http.annotation.Controller; -import io.micronaut.http.annotation.Get; -import io.micronaut.http.annotation.Post; -import io.micronaut.http.annotation.Produces; -import io.micronaut.http.annotation.QueryValue; +import io.micronaut.http.annotation.*; import io.micronaut.views.ModelAndView; import io.micronaut.views.View; import org.slf4j.Logger; @@ -92,6 +87,7 @@ public HttpResponse> edit(@QueryValue(value = "index", defau } @Post("add") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public ModelAndView> add(@Body ServerForm serverForm) { boolean active = "on".equals(serverForm.getActiveOn()); From e388c6965187ab3c8cdce1485137e3b0f8c71cd8 Mon Sep 17 00:00:00 2001 From: darkweird Date: Tue, 30 Nov 2021 15:05:28 +0300 Subject: [PATCH 17/20] fix(micronauts): fix artifact repositories registration loading --- .../module/RepositoryRegistrar.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/org/terasology/module/RepositoryRegistrar.java diff --git a/src/main/java/org/terasology/module/RepositoryRegistrar.java b/src/main/java/org/terasology/module/RepositoryRegistrar.java new file mode 100644 index 0000000..889eb3a --- /dev/null +++ b/src/main/java/org/terasology/module/RepositoryRegistrar.java @@ -0,0 +1,35 @@ +package org.terasology.module; + +import io.micronaut.context.event.ApplicationEventListener; +import io.micronaut.context.event.StartupEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.terasology.web.model.artifactory.ArtifactoryRepo; +import org.terasology.web.services.impl.ModuleListServiceImpl; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; +import java.io.IOException; +import java.nio.file.Paths; + +@Singleton +public class RepositoryRegistrar implements ApplicationEventListener { + private final static Logger logger = LoggerFactory.getLogger(RepositoryRegistrar.class); + + @Inject + Provider moduleListServiceProvider; + + @Override + public void onApplicationEvent(StartupEvent event) { + logger.info("Register Repositories"); + try { + ArtifactoryRepo repo = ArtifactoryRepo.release("http://artifactory.terasology.org/artifactory", "virtual-repo-live", "org/terasology/modules", Paths.get("cache")); + moduleListServiceProvider.get().addRepository( + repo + ); + } catch (IOException e) { + logger.error("Cannot register modules repository" + e); + } + } +} From d3bd30999e0d4f6194ddc50dc554d8388f582bba Mon Sep 17 00:00:00 2001 From: darkweird Date: Tue, 30 Nov 2021 15:05:48 +0300 Subject: [PATCH 18/20] fix(micronauts): fix metadata loading for modules --- .../java/org/terasology/web/services/impl/ZipExtractor.java | 3 ++- src/main/resources/application-test.yml | 4 ++++ src/main/resources/application.yml | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/terasology/web/services/impl/ZipExtractor.java b/src/main/java/org/terasology/web/services/impl/ZipExtractor.java index 5feca86..1f04ff8 100644 --- a/src/main/java/org/terasology/web/services/impl/ZipExtractor.java +++ b/src/main/java/org/terasology/web/services/impl/ZipExtractor.java @@ -3,6 +3,7 @@ package org.terasology.web.services.impl; +import io.micronaut.context.annotation.Value; import org.terasology.module.ModuleMetadata; import org.terasology.module.ModuleMetadataJsonAdapter; import org.terasology.web.services.api.MetadataExtractor; @@ -33,7 +34,7 @@ public class ZipExtractor implements MetadataExtractor { /** * @param filenames the collection file names that match. The first match is returned. */ - public ZipExtractor(String... filenames) { + public ZipExtractor(@Value("${meta-server.module.metadataFileNames}") String... filenames) { this.filename = Arrays.asList(filenames); } diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 13616f2..a90fbd3 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -11,3 +11,7 @@ datasources: meta-server: edit.secret: "foo" dbip.api.key: "bar" + module: + metadataFileNames: + - module.json + - module.txt \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 474c683..4b23cb8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -17,4 +17,8 @@ datasources: meta-server: cache.folder: "./cache" table.name: "servers" + module: + metadataFileNames: + - module.json + - module.txt From ebccbea2736e51a759cfd1bedb83cc142449059b Mon Sep 17 00:00:00 2001 From: darkweird Date: Tue, 30 Nov 2021 16:05:44 +0300 Subject: [PATCH 19/20] refactor(micronauts): Provide data-driven configs for repository handling --- README.md | 4 +- .../module/RepositoryRegistrar.java | 35 --------------- .../impl/ArtifactRepositoryConfig.java | 43 +++++++++++++++++++ .../services/impl/ModuleListServiceImpl.java | 19 +++----- .../web/services/impl/RepositoryFactory.java | 31 +++++++++++++ src/main/resources/application-dev.yml | 31 +++++++++++++ src/main/resources/application-test.yml | 6 +-- src/main/resources/application.yml | 5 +++ 8 files changed, 118 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/org/terasology/module/RepositoryRegistrar.java create mode 100644 src/main/java/org/terasology/web/services/impl/ArtifactRepositoryConfig.java create mode 100644 src/main/java/org/terasology/web/services/impl/RepositoryFactory.java create mode 100644 src/main/resources/application-dev.yml diff --git a/README.md b/README.md index ecf2f90..e0f464a 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Run locally Gradle-way: 1. Clone 2. Go to Project Dir -3. Set environment variable `MICRONAUT_ENVIRONMENTS` to `test` (local h2 database) +3. Set environment variable `MICRONAUT_ENVIRONMENTS` to `dev` (local h2 database) 4. `./gradlew run` at Linux/Macos or `gradlew run` at Windows 5. found at logs entry like `[main] INFO io.micronaut.runtime.Micronaut - Startup completed in 624ms. Server Running: http://localhost:39195` 6. Go To url described at logs with your browser @@ -29,7 +29,7 @@ Docker-way: 1. Clone 2. Go To Project Dir 3. Run `docker build . -t test-meta-server` -4. Run `docker run --env "MICRONAUT_ENVIRONMENTS=test" test-meta-server` +4. Run `docker run --env "MICRONAUT_ENVIRONMENTS=dev" test-meta-server` Deployment ------------- diff --git a/src/main/java/org/terasology/module/RepositoryRegistrar.java b/src/main/java/org/terasology/module/RepositoryRegistrar.java deleted file mode 100644 index 889eb3a..0000000 --- a/src/main/java/org/terasology/module/RepositoryRegistrar.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.terasology.module; - -import io.micronaut.context.event.ApplicationEventListener; -import io.micronaut.context.event.StartupEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.terasology.web.model.artifactory.ArtifactoryRepo; -import org.terasology.web.services.impl.ModuleListServiceImpl; - -import javax.inject.Inject; -import javax.inject.Provider; -import javax.inject.Singleton; -import java.io.IOException; -import java.nio.file.Paths; - -@Singleton -public class RepositoryRegistrar implements ApplicationEventListener { - private final static Logger logger = LoggerFactory.getLogger(RepositoryRegistrar.class); - - @Inject - Provider moduleListServiceProvider; - - @Override - public void onApplicationEvent(StartupEvent event) { - logger.info("Register Repositories"); - try { - ArtifactoryRepo repo = ArtifactoryRepo.release("http://artifactory.terasology.org/artifactory", "virtual-repo-live", "org/terasology/modules", Paths.get("cache")); - moduleListServiceProvider.get().addRepository( - repo - ); - } catch (IOException e) { - logger.error("Cannot register modules repository" + e); - } - } -} diff --git a/src/main/java/org/terasology/web/services/impl/ArtifactRepositoryConfig.java b/src/main/java/org/terasology/web/services/impl/ArtifactRepositoryConfig.java new file mode 100644 index 0000000..bbb3cd3 --- /dev/null +++ b/src/main/java/org/terasology/web/services/impl/ArtifactRepositoryConfig.java @@ -0,0 +1,43 @@ +package org.terasology.web.services.impl; + +import io.micronaut.context.annotation.EachProperty; + +@EachProperty(value = "meta-server.module.repos", list = true) +public class ArtifactRepositoryConfig { + private String url; + private String repoName; + private String group; + private String cacheFolder; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getRepoName() { + return repoName; + } + + public void setRepoName(String repoName) { + this.repoName = repoName; + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public String getCacheFolder() { + return cacheFolder; + } + + public void setCacheFolder(String cacheFolder) { + this.cacheFolder = cacheFolder; + } +} diff --git a/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java b/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java index f192ef3..211594f 100644 --- a/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java +++ b/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java @@ -7,14 +7,8 @@ import io.micronaut.context.annotation.Value; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.module.DependencyResolver; import org.terasology.module.Module; -import org.terasology.module.ModuleMetadata; -import org.terasology.module.ModuleMetadataJsonAdapter; -import org.terasology.module.ModuleRegistry; -import org.terasology.module.RemoteModuleExtension; -import org.terasology.module.ResolutionResult; -import org.terasology.module.TableModuleRegistry; +import org.terasology.module.*; import org.terasology.naming.Name; import org.terasology.naming.Version; import org.terasology.web.model.artifactory.ArtifactInfo; @@ -31,13 +25,7 @@ import java.io.Writer; import java.nio.charset.StandardCharsets; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -64,16 +52,19 @@ public class ModuleListServiceImpl implements ModuleListService { public ModuleListServiceImpl( @Value("${meta-server.cache.folder}") Path cacheFolder, + Collection repositories, MetadataExtractor extractor) { this.cacheFolder = cacheFolder; this.cacheFolder.toFile().mkdirs(); this.extractor = extractor; + this.repositories.addAll(repositories); for (RemoteModuleExtension ext : RemoteModuleExtension.values()) { metadataAdapter.registerExtension(ext.getKey(), ext.getValueType()); } } + @Deprecated public void addRepository(ArtifactRepository repo) { repositories.add(repo); } diff --git a/src/main/java/org/terasology/web/services/impl/RepositoryFactory.java b/src/main/java/org/terasology/web/services/impl/RepositoryFactory.java new file mode 100644 index 0000000..6053911 --- /dev/null +++ b/src/main/java/org/terasology/web/services/impl/RepositoryFactory.java @@ -0,0 +1,31 @@ +package org.terasology.web.services.impl; + +import io.micronaut.context.annotation.EachBean; +import io.micronaut.context.annotation.Factory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.terasology.web.model.artifactory.ArtifactRepository; +import org.terasology.web.model.artifactory.ArtifactoryRepo; + +import java.io.IOException; +import java.nio.file.Paths; + +@Factory +public class RepositoryFactory { + private final static Logger logger = LoggerFactory.getLogger(RepositoryFactory.class); + + + @EachBean(ArtifactRepositoryConfig.class) + public ArtifactRepository repository(ArtifactRepositoryConfig repoConfig) { + try { + return ArtifactoryRepo.release( + repoConfig.getUrl(), + repoConfig.getRepoName(), + repoConfig.getGroup(), + Paths.get(repoConfig.getCacheFolder())); + } catch (IOException e) { + logger.error("Cannot register Repository", e); + } + return null; + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..586ed34 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,31 @@ +micronaut: + application: + name: meta-server + server: + port: 8080 + router: + static-resources: + base: + paths: + - "classpath:static" + +datasources: + default: + url: jdbc:h2:mem:testdb + driverClassName: org.h2.Driver + username: sa + password: password + +meta-server: + cache.folder: "./cache" + table.name: "servers" + module: + metadataFileNames: + - module.json + - module.txt + repos: + - url: http://artifactory.terasology.org/artifactory + repo-name: virtual-repo-live + group: org/terasology/modules + cache-folder: cache + diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a90fbd3..235f88d 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -10,8 +10,4 @@ datasources: meta-server: edit.secret: "foo" - dbip.api.key: "bar" - module: - metadataFileNames: - - module.json - - module.txt \ No newline at end of file + dbip.api.key: "bar" \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 4b23cb8..8f59519 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -21,4 +21,9 @@ meta-server: metadataFileNames: - module.json - module.txt + repos: + - url: http://artifactory.terasology.org/artifactory + repo-name: virtual-repo-live + group: org/terasology/modules + cache-folder: cache From 987c6f4f9cf1dccb8d4a2b1400f9f88a670409ae Mon Sep 17 00:00:00 2001 From: darkweird Date: Tue, 18 Oct 2022 18:06:27 +0300 Subject: [PATCH 20/20] refactor(micronauts): bump up micronauts version --- gradle.properties | 2 +- .../web/controllers/ModuleController.java | 8 +- .../services/impl/ModuleListServiceImpl.java | 18 +- .../services/impl/ServerListServiceImpl.java | 2 +- .../web/services/impl/ZipExtractor.java | 2 +- .../services/impl/db/JooqDatabaseService.java | 2 +- .../impl/geo/dbip/DbIpGeoLocationService.java | 2 +- src/main/resources/views/module-info.ftl | 169 +++++++++--------- .../java/org/terasology/master/BaseTests.java | 6 +- .../org/terasology/master/JooqDbTest.java | 4 +- .../terasology/master/ModuleJsonListTest.java | 4 +- .../org/terasology/master/ModuleShowTest.java | 4 +- .../terasology/master/ModuleUpdateTest.java | 2 +- .../master/ServerHtmlContentTest.java | 3 +- .../terasology/master/ServerJsonListTest.java | 2 +- .../org/terasology/master/ValidatorTests.java | 2 +- .../master/services/DummyExtractor.java | 2 +- .../services/DummyGeoLocationService.java | 2 +- 18 files changed, 112 insertions(+), 124 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4032aa5..5ed16d3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,4 @@ version=3.0.0 versioneye.projectkey=maven2_master_server_1 versioneye.projectid=55352d6edc39815abf0007ad -micronautVersion=2.0.3 +micronautVersion=3.7.2 diff --git a/src/main/java/org/terasology/web/controllers/ModuleController.java b/src/main/java/org/terasology/web/controllers/ModuleController.java index 9e3a7f5..c07c3d0 100644 --- a/src/main/java/org/terasology/web/controllers/ModuleController.java +++ b/src/main/java/org/terasology/web/controllers/ModuleController.java @@ -112,7 +112,7 @@ public HttpResponse> listModuleLatest(HttpRequest httpReq String path = uri.getPath().substring(0, pathLen - "latest".length()); Module latest = model.getLatestModuleVersion(new Name(module)); if (latest == null) { - return HttpResponse.notFound(); + return HttpResponse.notFound(Map.of("version", VersionInfo.getVersion())); } String ver = latest.getVersion().toString(); URI redirect = URI.create(path + ver); @@ -127,7 +127,7 @@ public HttpResponse> showModuleLatest(HttpRequest httpReq String path = uriInfo.getPath().substring(0, pathLen - "latest".length()); Module latest = model.getLatestModuleVersion(new Name(module)); if (latest == null) { - return HttpResponse.notFound(); + return HttpResponse.notFound(Map.of("version", VersionInfo.getVersion())); } String ver = latest.getVersion().toString(); URI redirect = URI.create(path + ver); @@ -145,7 +145,7 @@ public HttpResponse> showModuleVersion(@PathVariable("module Module mod = model.getModule(moduleName, modVersion); if (mod == null) { logger.warn("No entry for module '{}' found", module); - return HttpResponse.notFound(); + return HttpResponse.notFound(Map.of("version", VersionInfo.getVersion())); } ModuleMetadata meta = mod.getMetadata(); @@ -162,7 +162,7 @@ public HttpResponse> showModuleVersion(@PathVariable("module return HttpResponse.ok(dataModel); } catch (VersionParseException e) { logger.warn("Invalid version for module '{}' specified: {}", module, version); - return HttpResponse.notFound(); + return HttpResponse.notFound(Map.of("version", VersionInfo.getVersion())); } } } diff --git a/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java b/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java index 0623c3f..e7766cb 100644 --- a/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java +++ b/src/main/java/org/terasology/web/services/impl/ModuleListServiceImpl.java @@ -5,10 +5,10 @@ import com.google.common.io.Files; import io.micronaut.context.annotation.Value; +import jakarta.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.module.Module; -import org.terasology.module.*; import org.terasology.naming.Name; import org.terasology.naming.Version; import org.terasology.web.model.artifactory.ArtifactInfo; @@ -18,7 +18,6 @@ import org.terasology.web.services.api.ModuleListService; import javax.annotation.concurrent.ThreadSafe; -import javax.inject.Singleton; import java.io.File; import java.io.IOException; import java.io.Reader; @@ -35,25 +34,15 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.ReentrantReadWriteLock; -import javax.annotation.concurrent.ThreadSafe; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.terasology.module.DependencyResolver; -import org.terasology.module.Module; import org.terasology.module.ModuleMetadata; import org.terasology.module.ModuleMetadataJsonAdapter; import org.terasology.module.ModuleRegistry; import org.terasology.module.RemoteModuleExtension; import org.terasology.module.ResolutionResult; import org.terasology.module.TableModuleRegistry; -import org.terasology.naming.Name; -import org.terasology.naming.Version; -import org.terasology.web.artifactory.ArtifactInfo; -import org.terasology.web.artifactory.ArtifactRepository; import com.google.common.collect.ImmutableList; -import com.google.common.io.Files; /** * Provides a list of modules. @@ -78,10 +67,7 @@ public class ModuleListServiceImpl implements ModuleListService { private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true); - public ModuleListServiceImpl( - @Value("${meta-server.cache.folder}") Path cacheFolder, - Collection repositories, - MetadataExtractor extractor) { + public ModuleListServiceImpl(@Value("${meta-server.cache.folder}") Path cacheFolder, Collection repositories, MetadataExtractor extractor) { this.cacheFolder = cacheFolder; this.cacheFolder.toFile().mkdirs(); this.extractor = extractor; diff --git a/src/main/java/org/terasology/web/services/impl/ServerListServiceImpl.java b/src/main/java/org/terasology/web/services/impl/ServerListServiceImpl.java index 2112b53..6904746 100644 --- a/src/main/java/org/terasology/web/services/impl/ServerListServiceImpl.java +++ b/src/main/java/org/terasology/web/services/impl/ServerListServiceImpl.java @@ -18,6 +18,7 @@ import com.google.common.base.Preconditions; import io.micronaut.context.annotation.Value; +import jakarta.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.web.model.server.Result; @@ -25,7 +26,6 @@ import org.terasology.web.services.api.DatabaseService; import org.terasology.web.services.api.ServerListService; -import javax.inject.Singleton; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; diff --git a/src/main/java/org/terasology/web/services/impl/ZipExtractor.java b/src/main/java/org/terasology/web/services/impl/ZipExtractor.java index 1f04ff8..1338be3 100644 --- a/src/main/java/org/terasology/web/services/impl/ZipExtractor.java +++ b/src/main/java/org/terasology/web/services/impl/ZipExtractor.java @@ -4,11 +4,11 @@ package org.terasology.web.services.impl; import io.micronaut.context.annotation.Value; +import jakarta.inject.Singleton; import org.terasology.module.ModuleMetadata; import org.terasology.module.ModuleMetadataJsonAdapter; import org.terasology.web.services.api.MetadataExtractor; -import javax.inject.Singleton; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; diff --git a/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java b/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java index 3466e8e..51cb507 100644 --- a/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java +++ b/src/main/java/org/terasology/web/services/impl/db/JooqDatabaseService.java @@ -3,6 +3,7 @@ package org.terasology.web.services.impl.db; +import jakarta.inject.Singleton; import org.jooq.DSLContext; import org.jooq.Field; import org.jooq.InsertSetMoreStep; @@ -20,7 +21,6 @@ import org.terasology.web.services.api.GeoLocationService; import org.terasology.web.services.impl.geo.GeoLocation; -import javax.inject.Singleton; import javax.sql.DataSource; import java.io.IOException; import java.sql.Connection; diff --git a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java index e341a36..b4c7a49 100644 --- a/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java +++ b/src/main/java/org/terasology/web/services/impl/geo/dbip/DbIpGeoLocationService.java @@ -17,10 +17,10 @@ package org.terasology.web.services.impl.geo.dbip; import io.micronaut.context.annotation.Value; +import jakarta.inject.Singleton; import org.terasology.web.services.api.GeoLocationService; import org.terasology.web.services.impl.geo.GeoLocation; -import javax.inject.Singleton; import java.io.IOException; import java.net.InetAddress; diff --git a/src/main/resources/views/module-info.ftl b/src/main/resources/views/module-info.ftl index b2a071b..36acc62 100644 --- a/src/main/resources/views/module-info.ftl +++ b/src/main/resources/views/module-info.ftl @@ -3,86 +3,89 @@ <#include "metainfo.ftl"> - - -
- -<#assign tab = "modules"> -<#include "navigation.ftl"> - -<#if message??> - - - -
- - -

${meta.displayName}

-

${meta.version}

- -
-

${meta.description}

- -
-

Last Updated

-

- ${updated?date?string.long}
- ${updated?time?string.long} -

- -
-

Required Permissions

-

<#if meta.requiredPermissions?size == 0> - none - <#else> - ${meta.requiredPermissions?join(", ")} - -

- -
-

Dependencies

-

<#if meta.dependencies?size == 0> - none - <#else> - <#list meta.dependencies as dep> - ${dep.id} between ${dep.minVersion} and ${dep.maxVersion} - <#if dep.optional> - (optional) - -
- - -

- -
-

Resolved by

-

-<#if dependencies?size == 0> - Unresolved -<#else> - <#list dependencies as dep> - ${dep.id} ${dep.version}
- - (there may be other combinations) - -

-
- - - Download (${downloadSize} kB) - - -

-
- -
- -<#include "footer.ftl"> - -
- - + + +
+ + <#assign tab = "modules"> + <#include "navigation.ftl"> + + <#if message??> + + + <#if meta??> +
+ + +

${meta.displayName}

+

${meta.version}

+ +
+

${meta.description}

+ +
+

Last Updated

+

+ ${updated?date?string.long}
+ ${updated?time?string.long} +

+ +
+

Required Permissions

+

<#if meta.requiredPermissions?size == 0> + none + <#else> + ${meta.requiredPermissions?join(", ")} + +

+ +
+

Dependencies

+

<#if meta.dependencies?size == 0> + none + <#else> + <#list meta.dependencies as dep> + ${dep.id} between ${dep.minVersion} and ${dep.maxVersion} + <#if dep.optional> + (optional) + +
+ + +

+ +
+

Resolved by

+

+ <#if dependencies?size == 0> + Unresolved + <#else> + <#list dependencies as dep> + ${dep.id} ${dep.version}
+ + (there may be other combinations) + +

+
+ + + Download (${downloadSize} kB) + + +

+
+ +
+ + + + <#include "footer.ftl"> + +
+ + + diff --git a/src/test/java/org/terasology/master/BaseTests.java b/src/test/java/org/terasology/master/BaseTests.java index 0c2f3eb..509de21 100644 --- a/src/test/java/org/terasology/master/BaseTests.java +++ b/src/test/java/org/terasology/master/BaseTests.java @@ -1,6 +1,7 @@ package org.terasology.master; -import io.micronaut.test.annotation.MicronautTest; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.TestInstance; import org.terasology.master.services.DummyArtifactRepo; @@ -11,11 +12,10 @@ import org.terasology.web.services.impl.ModuleListServiceImpl; import org.terasology.web.services.impl.geo.GeoLocation; -import javax.inject.Inject; import java.io.IOException; import java.sql.SQLException; -@MicronautTest +@MicronautTest(environments = "test") @TestInstance(TestInstance.Lifecycle.PER_CLASS) public class BaseTests { diff --git a/src/test/java/org/terasology/master/JooqDbTest.java b/src/test/java/org/terasology/master/JooqDbTest.java index 18237a2..0828077 100644 --- a/src/test/java/org/terasology/master/JooqDbTest.java +++ b/src/test/java/org/terasology/master/JooqDbTest.java @@ -16,12 +16,12 @@ package org.terasology.master; -import io.micronaut.test.annotation.MicronautTest; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.terasology.web.services.api.DatabaseService; -import javax.inject.Inject; import java.util.Map; @MicronautTest diff --git a/src/test/java/org/terasology/master/ModuleJsonListTest.java b/src/test/java/org/terasology/master/ModuleJsonListTest.java index 0275e33..60cb52f 100644 --- a/src/test/java/org/terasology/master/ModuleJsonListTest.java +++ b/src/test/java/org/terasology/master/ModuleJsonListTest.java @@ -22,7 +22,8 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import io.micronaut.test.annotation.MicronautTest; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.terasology.module.ModuleMetadata; @@ -30,7 +31,6 @@ import org.terasology.naming.Name; import org.terasology.naming.Version; -import javax.inject.Inject; import java.io.IOException; import java.io.Reader; import java.io.StringReader; diff --git a/src/test/java/org/terasology/master/ModuleShowTest.java b/src/test/java/org/terasology/master/ModuleShowTest.java index 41cb847..2e4c5e6 100644 --- a/src/test/java/org/terasology/master/ModuleShowTest.java +++ b/src/test/java/org/terasology/master/ModuleShowTest.java @@ -21,11 +21,11 @@ import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import io.micronaut.test.annotation.MicronautTest; +import io.micronaut.test.extensions.junit5.annotation.MicronautTest; +import jakarta.inject.Inject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import javax.inject.Inject; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; diff --git a/src/test/java/org/terasology/master/ModuleUpdateTest.java b/src/test/java/org/terasology/master/ModuleUpdateTest.java index 5ade2a8..b89ecd5 100644 --- a/src/test/java/org/terasology/master/ModuleUpdateTest.java +++ b/src/test/java/org/terasology/master/ModuleUpdateTest.java @@ -23,12 +23,12 @@ import io.micronaut.http.HttpStatus; import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; +import jakarta.inject.Inject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.terasology.module.ModuleMetadata; import org.terasology.module.ModuleMetadataJsonAdapter; -import javax.inject.Inject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; diff --git a/src/test/java/org/terasology/master/ServerHtmlContentTest.java b/src/test/java/org/terasology/master/ServerHtmlContentTest.java index a042e3a..ea844bb 100644 --- a/src/test/java/org/terasology/master/ServerHtmlContentTest.java +++ b/src/test/java/org/terasology/master/ServerHtmlContentTest.java @@ -19,14 +19,13 @@ import io.micronaut.http.HttpRequest; import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; +import jakarta.inject.Inject; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import javax.inject.Inject; - /** * diff --git a/src/test/java/org/terasology/master/ServerJsonListTest.java b/src/test/java/org/terasology/master/ServerJsonListTest.java index c50b3d4..851438d 100644 --- a/src/test/java/org/terasology/master/ServerJsonListTest.java +++ b/src/test/java/org/terasology/master/ServerJsonListTest.java @@ -22,12 +22,12 @@ import io.micronaut.http.HttpRequest; import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; +import jakarta.inject.Inject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.terasology.web.model.server.ServerEntry; import org.terasology.web.services.impl.geo.dbip.DbIpGeoLocationService; -import javax.inject.Inject; import java.io.IOException; import java.io.Reader; import java.io.StringReader; diff --git a/src/test/java/org/terasology/master/ValidatorTests.java b/src/test/java/org/terasology/master/ValidatorTests.java index 8e3ceeb..a1ef6b1 100644 --- a/src/test/java/org/terasology/master/ValidatorTests.java +++ b/src/test/java/org/terasology/master/ValidatorTests.java @@ -23,13 +23,13 @@ import io.micronaut.http.HttpRequest; import io.micronaut.http.client.HttpClient; import io.micronaut.http.client.annotation.Client; +import jakarta.inject.Inject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.inject.Inject; import java.io.IOException; /** diff --git a/src/test/java/org/terasology/master/services/DummyExtractor.java b/src/test/java/org/terasology/master/services/DummyExtractor.java index 69ef82f..b0eb167 100644 --- a/src/test/java/org/terasology/master/services/DummyExtractor.java +++ b/src/test/java/org/terasology/master/services/DummyExtractor.java @@ -17,13 +17,13 @@ package org.terasology.master.services; import io.micronaut.context.annotation.Replaces; +import jakarta.inject.Singleton; import org.terasology.module.ModuleMetadata; import org.terasology.module.ModuleMetadataJsonAdapter; import org.terasology.module.RemoteModuleExtension; import org.terasology.web.services.api.MetadataExtractor; import org.terasology.web.services.impl.ZipExtractor; -import javax.inject.Singleton; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; diff --git a/src/test/java/org/terasology/master/services/DummyGeoLocationService.java b/src/test/java/org/terasology/master/services/DummyGeoLocationService.java index f1ff44e..80e70f5 100644 --- a/src/test/java/org/terasology/master/services/DummyGeoLocationService.java +++ b/src/test/java/org/terasology/master/services/DummyGeoLocationService.java @@ -17,10 +17,10 @@ package org.terasology.master.services; import io.micronaut.context.annotation.Primary; +import jakarta.inject.Singleton; import org.terasology.web.services.api.GeoLocationService; import org.terasology.web.services.impl.geo.GeoLocation; -import javax.inject.Singleton; import java.io.IOException; /**