From 43d6dc93c02365a2175eb7c583f63f380cc27deb Mon Sep 17 00:00:00 2001 From: Kavin <20838718+FireMasterK@users.noreply.github.com> Date: Wed, 16 Mar 2022 03:21:24 +0000 Subject: [PATCH] Use try with for sessions (#222) --- src/main/java/me/kavin/piped/Main.java | 12 +- .../java/me/kavin/piped/ServerLauncher.java | 12 +- .../piped/utils/DatabaseSessionFactory.java | 7 +- .../me/kavin/piped/utils/Multithreading.java | 8 +- .../me/kavin/piped/utils/ResponseHelper.java | 702 ++++++++---------- 5 files changed, 347 insertions(+), 394 deletions(-) diff --git a/src/main/java/me/kavin/piped/Main.java b/src/main/java/me/kavin/piped/Main.java index 98f738b..7a03911 100644 --- a/src/main/java/me/kavin/piped/Main.java +++ b/src/main/java/me/kavin/piped/Main.java @@ -31,8 +31,7 @@ public class Main { new Timer().scheduleAtFixedRate(new TimerTask() { @Override public void run() { - try { - Session s = DatabaseSessionFactory.createSession(); + try (Session s = DatabaseSessionFactory.createSession()) { CriteriaBuilder cb = s.getCriteriaBuilder(); CriteriaQuery criteria = cb.createQuery(PubSub.class); @@ -51,16 +50,13 @@ public class Main { for (PubSub pubsub : pubSubList) if (pubsub != null) Multithreading.runAsyncLimitedPubSub(() -> { - Session sess = DatabaseSessionFactory.createSession(); - try { + try (Session sess = DatabaseSessionFactory.createSession()) { ResponseHelper.subscribePubSub(pubsub.getId(), sess); } catch (Exception e) { e.printStackTrace(); } - sess.close(); }); - s.close(); } catch (Exception e) { e.printStackTrace(); } @@ -70,8 +66,7 @@ public class Main { new Timer().scheduleAtFixedRate(new TimerTask() { @Override public void run() { - try { - Session s = DatabaseSessionFactory.createSession(); + try (Session s = DatabaseSessionFactory.createSession()) { Transaction tr = s.getTransaction(); @@ -84,7 +79,6 @@ public class Main { tr.commit(); - s.close(); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/java/me/kavin/piped/ServerLauncher.java b/src/main/java/me/kavin/piped/ServerLauncher.java index 162fb10..9dd57a8 100644 --- a/src/main/java/me/kavin/piped/ServerLauncher.java +++ b/src/main/java/me/kavin/piped/ServerLauncher.java @@ -55,12 +55,12 @@ public class ServerLauncher extends MultithreadedHttpServerLauncher { new InputSource(new ByteArrayInputStream(request.loadBody().getResult().asArray()))); Multithreading.runAsync(() -> { - Session s = DatabaseSessionFactory.createSession(); - feed.getEntries().forEach(entry -> { - ResponseHelper.handleNewVideo(entry.getLinks().get(0).getHref(), - entry.getPublishedDate().getTime(), null, s); - }); - s.close(); + try (Session s = DatabaseSessionFactory.createSession()) { + for (var entry : feed.getEntries()) { + ResponseHelper.handleNewVideo(entry.getLinks().get(0).getHref(), + entry.getPublishedDate().getTime(), null, s); + } + } }); return HttpResponse.ofCode(204); diff --git a/src/main/java/me/kavin/piped/utils/DatabaseSessionFactory.java b/src/main/java/me/kavin/piped/utils/DatabaseSessionFactory.java index 6603f42..a1bd10f 100644 --- a/src/main/java/me/kavin/piped/utils/DatabaseSessionFactory.java +++ b/src/main/java/me/kavin/piped/utils/DatabaseSessionFactory.java @@ -1,14 +1,13 @@ package me.kavin.piped.utils; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.cfg.Configuration; - import me.kavin.piped.consts.Constants; import me.kavin.piped.utils.obj.db.Channel; import me.kavin.piped.utils.obj.db.PubSub; import me.kavin.piped.utils.obj.db.User; import me.kavin.piped.utils.obj.db.Video; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; public class DatabaseSessionFactory { diff --git a/src/main/java/me/kavin/piped/utils/Multithreading.java b/src/main/java/me/kavin/piped/utils/Multithreading.java index babb9e3..e11bea1 100644 --- a/src/main/java/me/kavin/piped/utils/Multithreading.java +++ b/src/main/java/me/kavin/piped/utils/Multithreading.java @@ -1,7 +1,9 @@ package me.kavin.piped.utils; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.function.Supplier; public class Multithreading { @@ -26,4 +28,8 @@ public class Multithreading { public static ExecutorService getCachedExecutor() { return es; } -} \ No newline at end of file + + public static CompletableFuture supplyAsync(Supplier supplier) { + return CompletableFuture.supplyAsync(supplier, es); + } +} diff --git a/src/main/java/me/kavin/piped/utils/ResponseHelper.java b/src/main/java/me/kavin/piped/utils/ResponseHelper.java index 0f0e6fe..dbeafbf 100644 --- a/src/main/java/me/kavin/piped/utils/ResponseHelper.java +++ b/src/main/java/me/kavin/piped/utils/ResponseHelper.java @@ -50,7 +50,6 @@ import javax.persistence.criteria.JoinType; import javax.persistence.criteria.Root; import java.io.IOException; import java.util.*; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import static java.nio.charset.StandardCharsets.UTF_8; @@ -66,25 +65,25 @@ public class ResponseHelper { public static byte[] streamsResponse(String videoId) throws Exception { - CompletableFuture futureStream = CompletableFuture.supplyAsync(() -> { + final var futureStream = Multithreading.supplyAsync(() -> { try { return StreamInfo.getInfo("https://www.youtube.com/watch?v=" + videoId); } catch (Exception e) { ExceptionUtils.rethrow(e); } return null; - }, Multithreading.getCachedExecutor()); + }); - CompletableFuture futureLbryId = CompletableFuture.supplyAsync(() -> { + final var futureLbryId = Multithreading.supplyAsync(() -> { try { return LbryHelper.getLBRYId(videoId); } catch (Exception e) { ExceptionHandler.handle(e); } return null; - }, Multithreading.getCachedExecutor()); + }); - CompletableFuture futureLBRY = CompletableFuture.supplyAsync(() -> { + final var futureLBRY = Multithreading.supplyAsync(() -> { try { String lbryId = futureLbryId.completeOnTimeout(null, 2, TimeUnit.SECONDS).get(); @@ -93,7 +92,7 @@ public class ResponseHelper { ExceptionHandler.handle(e); } return null; - }, Multithreading.getCachedExecutor()); + }); final List subtitles = new ObjectArrayList<>(); final List chapters = new ObjectArrayList<>(); @@ -187,35 +186,34 @@ public class ResponseHelper { info.getRelatedItems().forEach(o -> relatedStreams.add(collectRelatedStream(o))); Multithreading.runAsync(() -> { - Session s = DatabaseSessionFactory.createSession(); + try (Session s = DatabaseSessionFactory.createSession()) { - me.kavin.piped.utils.obj.db.Channel channel = DatabaseHelper.getChannelFromId(s, info.getId()); + me.kavin.piped.utils.obj.db.Channel channel = DatabaseHelper.getChannelFromId(s, info.getId()); - if (channel != null) { - if (channel.isVerified() != info.isVerified() - || !channel.getUploaderAvatar().equals(info.getAvatarUrl())) { - channel.setVerified(info.isVerified()); - channel.setUploaderAvatar(info.getAvatarUrl()); - if (!s.getTransaction().isActive()) - s.getTransaction().begin(); - s.update(channel); - s.getTransaction().commit(); - } - for (StreamInfoItem item : info.getRelatedItems()) { - long time = item.getUploadDate() != null - ? item.getUploadDate().offsetDateTime().toInstant().toEpochMilli() - : System.currentTimeMillis(); - if (System.currentTimeMillis() - time < TimeUnit.DAYS.toMillis(Constants.FEED_RETENTION)) - try { - String id = YOUTUBE_SERVICE.getStreamLHFactory().getId(item.getUrl()); - updateVideo(id, item, time, true); - } catch (Exception e) { - ExceptionHandler.handle(e); - } + if (channel != null) { + if (channel.isVerified() != info.isVerified() + || !channel.getUploaderAvatar().equals(info.getAvatarUrl())) { + channel.setVerified(info.isVerified()); + channel.setUploaderAvatar(info.getAvatarUrl()); + if (!s.getTransaction().isActive()) + s.getTransaction().begin(); + s.update(channel); + s.getTransaction().commit(); + } + for (StreamInfoItem item : info.getRelatedItems()) { + long time = item.getUploadDate() != null + ? item.getUploadDate().offsetDateTime().toInstant().toEpochMilli() + : System.currentTimeMillis(); + if (System.currentTimeMillis() - time < TimeUnit.DAYS.toMillis(Constants.FEED_RETENTION)) + try { + String id = YOUTUBE_SERVICE.getStreamLHFactory().getId(item.getUrl()); + updateVideo(id, item, time, true); + } catch (Exception e) { + ExceptionHandler.handle(e); + } + } } } - - s.close(); }); String nextpage = null; @@ -527,40 +525,38 @@ public class ResponseHelper { user = user.toLowerCase(); - Session s = DatabaseSessionFactory.createSession(); - CriteriaBuilder cb = s.getCriteriaBuilder(); - CriteriaQuery cr = cb.createQuery(User.class); - Root root = cr.from(User.class); - cr.select(root).where(root.get("username").in(user)); - boolean registered = s.createQuery(cr).uniqueResult() != null; + try (Session s = DatabaseSessionFactory.createSession()) { + CriteriaBuilder cb = s.getCriteriaBuilder(); + CriteriaQuery cr = cb.createQuery(User.class); + Root root = cr.from(User.class); + cr.select(root).where(cb.equal(root.get("username"), user)); + boolean registered = s.createQuery(cr).uniqueResult() != null; - if (registered) { - s.close(); - return Constants.mapper.writeValueAsBytes(new AlreadyRegisteredResponse()); + if (registered) { + return Constants.mapper.writeValueAsBytes(new AlreadyRegisteredResponse()); + } + + if (Constants.COMPROMISED_PASSWORD_CHECK) { + String sha1Hash = DigestUtils.sha1Hex(pass).toUpperCase(); + String prefix = sha1Hash.substring(0, 5); + String suffix = sha1Hash.substring(5); + String[] entries = RequestUtils + .sendGet("https://api.pwnedpasswords.com/range/" + prefix, "github.com/TeamPiped/Piped-Backend") + .split("\n"); + for (String entry : entries) + if (StringUtils.substringBefore(entry, ":").equals(suffix)) + return Constants.mapper.writeValueAsBytes(new CompromisedPasswordResponse()); + } + + User newuser = new User(user, argon2PasswordEncoder.encode(pass), Collections.emptyList()); + + s.save(newuser); + s.getTransaction().begin(); + s.getTransaction().commit(); + + + return Constants.mapper.writeValueAsBytes(new LoginResponse(newuser.getSessionId())); } - - if (Constants.COMPROMISED_PASSWORD_CHECK) { - String sha1Hash = DigestUtils.sha1Hex(pass).toUpperCase(); - String prefix = sha1Hash.substring(0, 5); - String suffix = sha1Hash.substring(5); - String[] entries = RequestUtils - .sendGet("https://api.pwnedpasswords.com/range/" + prefix, "github.com/TeamPiped/Piped-Backend") - .split("\n"); - for (String entry : entries) - if (StringUtils.substringBefore(entry, ":").equals(suffix)) - return Constants.mapper.writeValueAsBytes(new CompromisedPasswordResponse()); - } - - User newuser = new User(user, argon2PasswordEncoder.encode(pass), Collections.emptyList()); - - s.save(newuser); - s.getTransaction().begin(); - s.getTransaction().commit(); - - s.close(); - - return Constants.mapper.writeValueAsBytes(new LoginResponse(newuser.getSessionId())); - } private static final BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder(); @@ -573,394 +569,352 @@ public class ResponseHelper { user = user.toLowerCase(); - Session s = DatabaseSessionFactory.createSession(); - CriteriaBuilder cb = s.getCriteriaBuilder(); - CriteriaQuery cr = cb.createQuery(User.class); - Root root = cr.from(User.class); - cr.select(root).where(root.get("username").in(user)); + try (Session s = DatabaseSessionFactory.createSession()) { + CriteriaBuilder cb = s.getCriteriaBuilder(); + CriteriaQuery cr = cb.createQuery(User.class); + Root root = cr.from(User.class); + cr.select(root).where(root.get("username").in(user)); - User dbuser = s.createQuery(cr).uniqueResult(); + User dbuser = s.createQuery(cr).uniqueResult(); - if (dbuser != null) { - String hash = dbuser.getPassword(); - if (hash.startsWith("$argon2")) { - if (argon2PasswordEncoder.matches(pass, hash)) { - s.close(); + if (dbuser != null) { + String hash = dbuser.getPassword(); + if (hash.startsWith("$argon2")) { + if (argon2PasswordEncoder.matches(pass, hash)) { + return Constants.mapper.writeValueAsBytes(new LoginResponse(dbuser.getSessionId())); + } + } else if (bcryptPasswordEncoder.matches(pass, hash)) { return Constants.mapper.writeValueAsBytes(new LoginResponse(dbuser.getSessionId())); } - } else if (bcryptPasswordEncoder.matches(pass, hash)) { - s.close(); - return Constants.mapper.writeValueAsBytes(new LoginResponse(dbuser.getSessionId())); } + + return Constants.mapper.writeValueAsBytes(new IncorrectCredentialsResponse()); } - - s.close(); - - return Constants.mapper.writeValueAsBytes(new IncorrectCredentialsResponse()); - } public static byte[] subscribeResponse(String session, String channelId) throws IOException { - Session s = DatabaseSessionFactory.createSession(); + try (Session s = DatabaseSessionFactory.createSession()) { - User user = DatabaseHelper.getUserFromSessionWithSubscribed(s, session); + User user = DatabaseHelper.getUserFromSessionWithSubscribed(s, session); - if (user != null) { - if (!user.getSubscribed().contains(channelId)) { + if (user != null) { + if (!user.getSubscribed().contains(channelId)) { - s.getTransaction().begin(); - s.createNativeQuery("insert into users_subscribed (subscriber, channel) values (?,?)") - .setParameter(1, user.getId()).setParameter(2, channelId).executeUpdate(); - s.getTransaction().commit(); - s.close(); + s.getTransaction().begin(); + s.createNativeQuery("insert into users_subscribed (subscriber, channel) values (?,?)") + .setParameter(1, user.getId()).setParameter(2, channelId).executeUpdate(); + s.getTransaction().commit(); - Multithreading.runAsync(() -> { - Session sess = DatabaseSessionFactory.createSession(); - var channel = DatabaseHelper.getChannelFromId(sess, channelId); + Multithreading.runAsync(() -> { + try (Session sess = DatabaseSessionFactory.createSession()) { + var channel = DatabaseHelper.getChannelFromId(sess, channelId); - if (channel == null) { - ChannelInfo info = null; + if (channel == null) { + ChannelInfo info = null; - try { - info = ChannelInfo.getInfo("https://youtube.com/channel/" + channelId); - } catch (IOException | ExtractionException e) { - ExceptionUtils.rethrow(e); - } + try { + info = ChannelInfo.getInfo("https://youtube.com/channel/" + channelId); + } catch (IOException | ExtractionException e) { + ExceptionUtils.rethrow(e); + } - channel = new me.kavin.piped.utils.obj.db.Channel(channelId, info.getName(), - info.getAvatarUrl(), info.isVerified()); - sess.save(channel); - sess.beginTransaction().commit(); + channel = new me.kavin.piped.utils.obj.db.Channel(channelId, info.getName(), + info.getAvatarUrl(), info.isVerified()); + sess.save(channel); + sess.beginTransaction().commit(); - Multithreading.runAsync(() -> { - try { - Session sessSub = DatabaseSessionFactory.createSession(); - subscribePubSub(channelId, sessSub); - sessSub.close(); - } catch (Exception e) { - ExceptionHandler.handle(e); + Multithreading.runAsync(() -> { + try (Session sessSub = DatabaseSessionFactory.createSession()) { + subscribePubSub(channelId, sessSub); + } catch (Exception e) { + ExceptionHandler.handle(e); + } + }); + + for (StreamInfoItem item : info.getRelatedItems()) { + long time = item.getUploadDate() != null + ? item.getUploadDate().offsetDateTime().toInstant().toEpochMilli() + : System.currentTimeMillis(); + if ((System.currentTimeMillis() - time) < TimeUnit.DAYS.toMillis(Constants.FEED_RETENTION)) + handleNewVideo(item.getUrl(), time, channel, sess); + } } - }); - - for (StreamInfoItem item : info.getRelatedItems()) { - long time = item.getUploadDate() != null - ? item.getUploadDate().offsetDateTime().toInstant().toEpochMilli() - : System.currentTimeMillis(); - if ((System.currentTimeMillis() - time) < TimeUnit.DAYS.toMillis(Constants.FEED_RETENTION)) - handleNewVideo(item.getUrl(), time, channel, sess); } - } + }); + } - sess.close(); - }); + return Constants.mapper.writeValueAsBytes(new AcceptedResponse()); } - return Constants.mapper.writeValueAsBytes(new AcceptedResponse()); + + return Constants.mapper.writeValueAsBytes(new AuthenticationFailureResponse()); } - s.close(); - - return Constants.mapper.writeValueAsBytes(new AuthenticationFailureResponse()); - } public static byte[] unsubscribeResponse(String session, String channelId) throws IOException { - Session s = DatabaseSessionFactory.createSession(); + try (Session s = DatabaseSessionFactory.createSession()) { + User user = DatabaseHelper.getUserFromSession(s, session); - User user = DatabaseHelper.getUserFromSession(s, session); - - if (user != null) { - s.getTransaction().begin(); - s.createNativeQuery("delete from users_subscribed where subscriber = :id and channel = :channel") - .setParameter("id", user.getId()).setParameter("channel", channelId).executeUpdate(); - s.getTransaction().commit(); - s.close(); - return Constants.mapper.writeValueAsBytes(new AcceptedResponse()); - } - - s.close(); - - return Constants.mapper.writeValueAsBytes(new AuthenticationFailureResponse()); - - } - - public static byte[] isSubscribedResponse(String session, String channelId) - throws IOException { - - Session s = DatabaseSessionFactory.createSession(); - - var cb = s.getCriteriaBuilder(); - var query = cb.createQuery(Long.class); - var root = query.from(User.class); - query.select(cb.count(root)) - .where(cb.and( - cb.equal(root.get("sessionId"), session), - cb.isMember(channelId, root.get("subscribed_ids")) - )); - var subscribed = s.createQuery(query).getSingleResult() > 0; - - s.close(); - - return Constants.mapper.writeValueAsBytes(new SubscribeStatusResponse(subscribed)); - } - - public static byte[] feedResponse(String session) - throws IOException { - - Session s = DatabaseSessionFactory.createSession(); - - User user = DatabaseHelper.getUserFromSession(s, session); - - if (user != null) { - - CriteriaBuilder cb = s.getCriteriaBuilder(); - - // Get all videos from subscribed channels, with channel info - CriteriaQuery