9 Commits

Author SHA1 Message Date
af9ea10b78 Labwork06 React is done? 2023-06-17 07:16:34 +04:00
9d4f79f1ae Thanks to thymeleaf, it's only taken 3 days to complete labwork5. 2023-06-15 22:06:57 +04:00
4f574dbb18 MVCs are done. 2023-05-25 02:45:16 +04:00
55c85931a4 LabWork4 is done. 2023-05-25 02:12:50 +04:00
ce0ea8903e A LITTLE MORE >_< 2023-05-24 02:30:24 +04:00
1240c7ec90 Backend changes. 2023-05-24 02:24:41 +04:00
84bcd7d64c Removing old front. 2023-05-24 01:46:58 +04:00
689b85bf12 Something was fixed and now it works. 2023-05-23 17:20:42 +04:00
5576f9e59e Backend part is done. 2023-05-23 15:46:50 +04:00
95 changed files with 20652 additions and 969 deletions

5
.gitignore vendored
View File

@@ -88,4 +88,7 @@ nbdist/
.nb-gradle/
### VS Code ###
.vscode/
.vscode/
/frontend/node_modules/
/.idea/
/.gradle/

Binary file not shown.

Binary file not shown.

BIN
.gradle/workspace-id.txt Normal file

Binary file not shown.

Binary file not shown.

2
.idea/compiler.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
<bytecodeTargetLevel target="17" />
</component>
</project>

6
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/data.mv.db" charset="windows-1251" />
</component>
</project>

2
.idea/misc.xml generated
View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="17" project-jdk-type="JavaSDK" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK" />
</project>

View File

@@ -16,10 +16,19 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.214'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5'
implementation 'com.auth0:java-jwt:4.4.0'
implementation 'junit:junit:4.13.2'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-devtools'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
implementation 'org.hibernate.validator:hibernate-validator'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}

Binary file not shown.

894
data.trace.db Normal file
View File

@@ -0,0 +1,894 @@
2023-05-24 22:46:14 jdbc[3]: exception
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "GENRE" not found; SQL statement:
select genre0_.id as id1_2_, genre0_.name as name2_2_ from genre genre0_ where genre0_.name like genre [42122-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
at org.h2.message.DbException.get(DbException.java:223)
at org.h2.message.DbException.get(DbException.java:199)
at org.h2.expression.ExpressionColumn.getColumnException(ExpressionColumn.java:244)
at org.h2.expression.ExpressionColumn.optimizeOther(ExpressionColumn.java:226)
at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:213)
at org.h2.expression.condition.CompareLike.optimize(CompareLike.java:150)
at org.h2.expression.Expression.optimizeCondition(Expression.java:148)
at org.h2.command.query.Select.prepareExpressions(Select.java:1177)
at org.h2.command.query.Query.prepare(Query.java:218)
at org.h2.command.Parser.prepareCommand(Parser.java:575)
at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:631)
at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:554)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1116)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:92)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2122)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2059)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2037)
at org.hibernate.loader.Loader.doQuery(Loader.java:956)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
at org.hibernate.loader.Loader.doList(Loader.java:2868)
at org.hibernate.loader.Loader.doList(Loader.java:2850)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2682)
at org.hibernate.loader.Loader.list(Loader.java:2677)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:540)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1454)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1665)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:198)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:90)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:155)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:143)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:145)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy2/jdk.proxy2.$Proxy118.findByName(Unknown Source)
at ru.ulstu.is.sbapp.Movie.Service.MovieService.fillRepo(MovieService.java:194)
at ru.ulstu.is.sbapp.Movie.Service.MovieService$$FastClassBySpringCGLIB$$bb620b80.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at ru.ulstu.is.sbapp.Movie.Service.MovieService$$EnhancerBySpringCGLIB$$7d3e602e.fillRepo(<generated>)
at ru.ulstu.is.sbapp.Movie.Controller.MovieController.insertMovies(MovieController.java:65)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
2023-05-24 23:03:06 jdbc[4]: exception
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "GENRE" not found; SQL statement:
select genre0_.id as id1_2_, genre0_.name as name2_2_ from genre genre0_ where genre0_.name like genre [42122-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
at org.h2.message.DbException.get(DbException.java:223)
at org.h2.message.DbException.get(DbException.java:199)
at org.h2.expression.ExpressionColumn.getColumnException(ExpressionColumn.java:244)
at org.h2.expression.ExpressionColumn.optimizeOther(ExpressionColumn.java:226)
at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:213)
at org.h2.expression.condition.CompareLike.optimize(CompareLike.java:150)
at org.h2.expression.Expression.optimizeCondition(Expression.java:148)
at org.h2.command.query.Select.prepareExpressions(Select.java:1177)
at org.h2.command.query.Query.prepare(Query.java:218)
at org.h2.command.Parser.prepareCommand(Parser.java:575)
at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:631)
at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:554)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1116)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:92)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2122)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2059)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2037)
at org.hibernate.loader.Loader.doQuery(Loader.java:956)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
at org.hibernate.loader.Loader.doList(Loader.java:2868)
at org.hibernate.loader.Loader.doList(Loader.java:2850)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2682)
at org.hibernate.loader.Loader.list(Loader.java:2677)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:540)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1454)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1665)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:198)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:90)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:155)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:143)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:145)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy2/jdk.proxy2.$Proxy118.findByName(Unknown Source)
at ru.ulstu.is.sbapp.Movie.Service.MovieService.fillRepo(MovieService.java:194)
at ru.ulstu.is.sbapp.Movie.Service.MovieService$$FastClassBySpringCGLIB$$bb620b80.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at ru.ulstu.is.sbapp.Movie.Service.MovieService$$EnhancerBySpringCGLIB$$e0f68ee9.fillRepo(<generated>)
at ru.ulstu.is.sbapp.Movie.Controller.MovieController.insertMovies(MovieController.java:65)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
2023-05-24 23:20:24 jdbc[3]: exception
org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "GENRE" not found; SQL statement:
select genre0_.id as id1_2_, genre0_.name as name2_2_ from genre genre0_ where genre0_.name like genre [42122-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:502)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
at org.h2.message.DbException.get(DbException.java:223)
at org.h2.message.DbException.get(DbException.java:199)
at org.h2.expression.ExpressionColumn.getColumnException(ExpressionColumn.java:244)
at org.h2.expression.ExpressionColumn.optimizeOther(ExpressionColumn.java:226)
at org.h2.expression.ExpressionColumn.optimize(ExpressionColumn.java:213)
at org.h2.expression.condition.CompareLike.optimize(CompareLike.java:150)
at org.h2.expression.Expression.optimizeCondition(Expression.java:148)
at org.h2.command.query.Select.prepareExpressions(Select.java:1177)
at org.h2.command.query.Query.prepare(Query.java:218)
at org.h2.command.Parser.prepareCommand(Parser.java:575)
at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:631)
at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:554)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1116)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:92)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288)
at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337)
at com.zaxxer.hikari.pool.HikariProxyConnection.prepareStatement(HikariProxyConnection.java)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:149)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:176)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:151)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:2122)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2059)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:2037)
at org.hibernate.loader.Loader.doQuery(Loader.java:956)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
at org.hibernate.loader.Loader.doList(Loader.java:2868)
at org.hibernate.loader.Loader.doList(Loader.java:2850)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2682)
at org.hibernate.loader.Loader.list(Loader.java:2677)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:540)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1454)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1649)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1665)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:198)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:90)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:155)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:143)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:159)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:145)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy2/jdk.proxy2.$Proxy118.findByName(Unknown Source)
at ru.ulstu.is.sbapp.Movie.Service.MovieService.fillRepo(MovieService.java:194)
at ru.ulstu.is.sbapp.Movie.Service.MovieService$$FastClassBySpringCGLIB$$bb620b80.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at ru.ulstu.is.sbapp.Movie.Service.MovieService$$EnhancerBySpringCGLIB$$f55ccaf0.fillRepo(<generated>)
at ru.ulstu.is.sbapp.Movie.Controller.MovieController.insertMovies(MovieController.java:66)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
2023-06-15 17:40:19 database: flush
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:395)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
at org.h2.mvstore.db.Store.<init>(Store.java:136)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.lambda$logDataSources$0(H2ConsoleAutoConfiguration.java:77)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.logDataSources(H2ConsoleAutoConfiguration.java:83)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.h2Console(H2ConsoleAutoConfiguration.java:70)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:203)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:97)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:86)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:260)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234)
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5219)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:478)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
... 99 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:178)
at org.h2.mvstore.FileStore.open(FileStore.java:128)
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
... 93 more
2023-06-15 17:40:21 database: flush
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:395)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
at org.h2.mvstore.db.Store.<init>(Store.java:136)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:175)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:173)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
... 66 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:178)
at org.h2.mvstore.FileStore.open(FileStore.java:128)
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
... 60 more
2023-06-15 17:40:23 database: flush
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:395)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
at org.h2.mvstore.db.Store.<init>(Store.java:136)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:44)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.jdbcStatement(GenerationTargetToDatabase.java:77)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:53)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:387)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:371)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:246)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:156)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:128)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:114)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:153)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:81)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
... 66 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:178)
at org.h2.mvstore.FileStore.open(FileStore.java:128)
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
... 60 more
2023-06-15 17:48:12 database: flush
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:395)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
at org.h2.mvstore.db.Store.<init>(Store.java:136)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.lambda$logDataSources$0(H2ConsoleAutoConfiguration.java:77)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.logDataSources(H2ConsoleAutoConfiguration.java:83)
at org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration.h2Console(H2ConsoleAutoConfiguration.java:70)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:203)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addServletContextInitializerBeans(ServletContextInitializerBeans.java:97)
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:86)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:260)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234)
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5219)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123)
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:478)
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
... 99 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:178)
at org.h2.mvstore.FileStore.open(FileStore.java:128)
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
... 93 more
2023-06-15 17:48:14 database: flush
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:395)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
at org.h2.mvstore.db.Store.<init>(Store.java:136)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:175)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:173)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
... 66 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:178)
at org.h2.mvstore.FileStore.open(FileStore.java:128)
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
... 60 more
2023-06-15 17:48:15 database: flush
org.h2.message.DbException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.get(DbException.java:212)
at org.h2.message.DbException.convert(DbException.java:395)
at org.h2.mvstore.db.Store.lambda$new$0(Store.java:125)
at org.h2.mvstore.MVStore.handleException(MVStore.java:3318)
at org.h2.mvstore.MVStore.panic(MVStore.java:593)
at org.h2.mvstore.MVStore.<init>(MVStore.java:469)
at org.h2.mvstore.MVStore$Builder.open(MVStore.java:4082)
at org.h2.mvstore.db.Store.<init>(Store.java:136)
at org.h2.engine.Database.<init>(Database.java:324)
at org.h2.engine.Engine.openSession(Engine.java:92)
at org.h2.engine.Engine.openSession(Engine.java:222)
at org.h2.engine.Engine.createSession(Engine.java:201)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:338)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:122)
at org.h2.Driver.connect(Driver.java:59)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:44)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.jdbcStatement(GenerationTargetToDatabase.java:77)
at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:53)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:387)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:371)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:246)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:156)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:128)
at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:114)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:153)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:81)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:414)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292)
at ru.ulstu.is.sbapp.SbappApplication.main(SbappApplication.java:13)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]" [50000-214]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:554)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:477)
... 66 more
Caused by: org.h2.mvstore.MVStoreException: The file is locked: E:/University/InternetProgramming/data.mv.db [2.1.214/7]
at org.h2.mvstore.DataUtils.newMVStoreException(DataUtils.java:1004)
at org.h2.mvstore.FileStore.open(FileStore.java:178)
at org.h2.mvstore.FileStore.open(FileStore.java:128)
at org.h2.mvstore.MVStore.<init>(MVStore.java:452)
... 60 more

View File

@@ -1,44 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>String manipulator</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
</head>
<body>
<div class = "flex-container" style = "flex-direction: column; display: flex; margin-top: 10px; width: 800px; height: 200px">
<div class = "flex-container" style = "flex-direction: row;display: flex; margin-bottom: 10px; gap: 10px;align-items: center;">
<input type="text" class="form-control form-control-sm" id="value" placeholder="Enter" style="border: 3px solid black;">
<select class = "form-select-sm" id="transformation" aria-label="form-select-sm example">
<option value="toupper" selected> toUpper</option>
<option value="removews"> removeWhitespaces</option>
<option value="removedigits"> removeDigits</option>
<option value="tolower"> toLower</option>
</select>
<input id = "result" class="form-control form-control-sm" readonly style="border: 3px dotted black;">
</div>
<div class = "flex-container" style = "flex-direction: row;display: flex; justify-content: center; gap: 10px">
<select class = "form-select-sm" id="converter" aria-label="form-select-sm example">
<option value="String" selected> String</option>
<option value="AString"> AString</option>
</select>
<button type="button" class = "btn btn-dark align-self-center" onclick="transform()">
Transform
</button>
</div>
</div>
<script>
async function transform()
{
const _value = document.getElementById("value").value
const func = document.getElementById("transformation").value
const convType = document.getElementById("converter").value
document.getElementById("result").value = await (await fetch(`http://localhost:8080/${func}?value=${_value}&type=${convType}`)).text()
}
</script>
</body>
</html>

View File

@@ -1,413 +0,0 @@
{
"name": "frontend",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/async": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
"integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
"dependencies": {
"lodash": "^4.17.14"
}
},
"node_modules/basic-auth": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
"dependencies": {
"safe-buffer": "5.1.2"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/bootstrap": {
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.2.3.tgz",
"integrity": "sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/twbs"
},
{
"type": "opencollective",
"url": "https://opencollective.com/bootstrap"
}
],
"peerDependencies": {
"@popperjs/core": "^2.11.6"
}
},
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"dependencies": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/corser": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz",
"integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"node_modules/get-intrinsic": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
"integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dependencies": {
"function-bind": "^1.1.1"
},
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"bin": {
"he": "bin/he"
}
},
"node_modules/html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
"integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
"dependencies": {
"whatwg-encoding": "^2.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"dependencies": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
"requires-port": "^1.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/http-server": {
"version": "14.1.1",
"resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz",
"integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==",
"dependencies": {
"basic-auth": "^2.0.1",
"chalk": "^4.1.2",
"corser": "^2.0.1",
"he": "^1.2.0",
"html-encoding-sniffer": "^3.0.0",
"http-proxy": "^1.18.1",
"mime": "^1.6.0",
"minimist": "^1.2.6",
"opener": "^1.5.1",
"portfinder": "^1.0.28",
"secure-compare": "3.0.1",
"union": "~0.5.0",
"url-join": "^4.0.1"
},
"bin": {
"http-server": "bin/http-server"
},
"engines": {
"node": ">=12"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"dependencies": {
"minimist": "^1.2.6"
},
"bin": {
"mkdirp": "bin/cmd.js"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/object-inspect": {
"version": "1.12.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
"integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/opener": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
"integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
"bin": {
"opener": "bin/opener-bin.js"
}
},
"node_modules/portfinder": {
"version": "1.0.32",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
"integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==",
"dependencies": {
"async": "^2.6.4",
"debug": "^3.2.7",
"mkdirp": "^0.5.6"
},
"engines": {
"node": ">= 0.12.0"
}
},
"node_modules/qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"dependencies": {
"side-channel": "^1.0.4"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/secure-compare": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz",
"integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw=="
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/union": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz",
"integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==",
"dependencies": {
"qs": "^6.4.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/url-join": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
"integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
},
"node_modules/whatwg-encoding": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
"integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
"dependencies": {
"iconv-lite": "0.6.3"
},
"engines": {
"node": ">=12"
}
}
}
}

17376
frontend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,42 @@
{
"name": "frontend",
"version": "1.0.0",
"main": "index.html",
"scripts": {
"start": "http-server -p 8081"
},
"author": "",
"license": "ISC",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.4.0",
"bootstrap": "^5.2.3",
"http-server": "^14.1.1"
"react": "^18.2.0",
"react-bootstrap": "^2.7.4",
"react-dom": "^18.2.0",
"react-router-dom": "^6.11.2",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

BIN
frontend/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

BIN
frontend/public/logo192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
frontend/public/logo512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

38
frontend/src/App.css Normal file
View File

@@ -0,0 +1,38 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

28
frontend/src/App.js Normal file
View File

@@ -0,0 +1,28 @@
import React from 'react';
import './style.css';
import 'bootstrap/dist/css/bootstrap.css';
import MainPage from './Pages/Mainpage'
import SearchPage from './Pages/Searchpage'
import LibPage from './Pages/Librarypage'
import RegPage from './Pages/Regpage'
import FilmInfo from './Pages/Filmpage'
import Loginpage from './Pages/Loginpage';
import { BrowserRouter as Router,Routes,Route} from 'react-router-dom';
export default function App() {
return (
<div>
<Router>
<Routes>
<Route path='/movie/:token' element={<MainPage/>} />
<Route path='/genre/:token' element={<SearchPage/>} />
<Route path='/library/:token' element={<LibPage/>} />
<Route path='*' element={<RegPage/>} />
<Route path='/movie/:token/:movieId' element={<FilmInfo/>} />
<Route path='/login' element={<Loginpage/>} />
</Routes>
</Router>
</div>
);
}

8
frontend/src/App.test.js Normal file
View File

@@ -0,0 +1,8 @@
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

View File

@@ -0,0 +1,124 @@
import axios from 'axios';
const host = "http://localhost:8080/api/1.0";
export async function registerUser(fullName,password,role)
{
console.log(fullName);
console.log(password);
console.log(role);
const response = await axios.post(`${host}/customer?fullName=${fullName}&password=${password}&role=${role}`);
if (response.status === 200) {
const customerDTO = response.data;
console.log(customerDTO);
return customerDTO;}
}
export async function loginUser(username,password)
{
const response = await axios.post(`${host}/customer/login`,JSON.stringify({"username": username,"password": password}));
if (response.status === 200) {
const token = response.data;
console.log(token);
return token;}
}
export async function getMovies()
{
const response = await axios.get(`${host}/movie`);
if (response.status === 200) {
const moviesData = response.data;
return moviesData;
}
}
export async function getMovie(movieId)
{
const response = await axios.get(`${host}/movie/${movieId}`);
if (response.status === 200) {
const movieDTO = response.data;
return movieDTO;}
}
export async function getCustomerMovies(token)
{
const response = await axios.get(`${host}/customer/movies?token=${token}`);
if (response.status === 200) {
const customerMovies = response.data;
return customerMovies;}
}
export async function acquireMovie(movieId,token)
{
const response = await axios.post(`${host}/movie/customer/movies/add/${movieId}?token=${token}`);
if (response.status === 200) {
const movieDTO= response.data;
return movieDTO;
}
}
export async function getMoviesByGenre(genre)
{
console.log(genre);
const response = await axios.get(`${host}/movie/movies/${genre}`);
console.log(response.data);
if (response.status === 200) {
const moviesData= response.data;
return moviesData;
}
}
export async function getCustomers()
{
const response = await axios.get(`${host}/customer`);
if (response.status === 200) {
const customers= response.data;
console.log(customers);
return customers;
}
}
export async function fillRepos()
{
console.log("here");
const response1 = await axios.post(`${host}/genre/fill`);
console.log(response1.data);
if(response1.status === 200)
{
const response2 = await axios.post(`${host}/movie/fill`);
}
}
export async function getGenres()
{
const response = await axios.get(`${host}/genre`);
if (response.status === 200) {
const genres= response.data;
console.log(genres);
return genres;
}
}
export async function updateMovie(movieId, modalData)
{
console.log(movieId);
console.log(modalData);
const response = await axios.put(`${host}/movie/${movieId}?title=${modalData["title"]}&length=${modalData["length"]}&score=${modalData["score"]}`);
}
export async function deleteMovie(movieId,token)
{
const response = await axios.delete(`${host}/movie/${movieId}?token=${token}`);
}
export async function removeCustomerMovie(movieId,token)
{
const response = await axios.delete(`${host}/movie/customer/movies/delete/${movieId}?token=${token}`);
}

View File

@@ -0,0 +1,24 @@
import React from 'react';
import { Link, useParams } from 'react-router-dom';
function Film({customerId,movieId,title, acquire,main,search})
{
const handleAcquireClick = () => {
acquire();
};
return (
<div className="flex-containerB" style={{flexDirection: "column", display: "flex", width: "250px",height:"350px",gap:"40px",alignItems:"center"}}>
<div className="flex-item1">
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" alt = "cover" width="100%" height="300px"/>
</div>
<div className="flex-item12 text-center" style={{ color:"white",fontSize: " 32px",fontWeight: "bold"}}><Link style={{color: "white", textDecoration: "none"}} to={`/movie/${customerId}/${movieId}`}>{title}</Link></div>
{main ? (
<button style= {{width:"50px"}}onClick={handleAcquireClick}>Add</button>
) : (main == null ? (<div></div>):(<button style= {{width:"90px"}}onClick={handleAcquireClick}>Remove</button>))}
</div>
);
}
export default Film;

View File

@@ -0,0 +1,10 @@
import React from "react";
const Footer = () => {
return (
<footer className="flex-item6">
<div className="text-center text-light p-2" style={{fontSize: "30px", fontWeight: "bold"}}>@2022 Copyright: BLSJY.com</div>
</footer>
);
}
export default Footer;

View File

@@ -0,0 +1,13 @@
const LibraryExtraBar = () =>{
return(
<div className="flex-container justify-content-center" id="filterbar" style={{display: "flex" , flex:"1" , flexDirection: "column", gap: "10px", textAlign: "center"}}>
<div className="flex-item-profile sidebar rounded-4 align-self-center">
<button className="button" style={{height: "110px", width:"160px", fontSize: "25px", opacity: "0.6"}} disabled="true">REVIEWED</button>
</div>
<div className="flex-item-search sidebar rounded-4 align-self-center">
<button className="button" style={{height: "110px", width:"160px", fontSize: "25px"}}>WATCHED</button>
</div>
</div>
);
}
export default LibraryExtraBar;

View File

@@ -0,0 +1,25 @@
import React from "react";
const ModalWindow = () => {
return (
<div className="modal fade" id="myModal" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button className="close" type="button" data-bs-dismiss="modal">&times;</button>
<h4 className="modal-title">Do you want to change or delete?</h4>
</div>
<div className="modal-body">
<input className="form-control" id="inputFilmName" type="name" value="" placeholder="Enter film name"/>
<input className="form-control" id="inputPic" type="url-pic" value="" placeholder="Enter url of film cover"/>
</div>
<div className="modal-footer">
<button className="btn btn-default" type="button" data-bs-dismiss="modal" onclick="changeMovie()">Change
<button className="btn btn-default" type="button" data-bs-dismiss="modal" onclick="deleteRequest()">Delete</button>
</button>
</div>
</div>
</div>
</div>
);
}
export default ModalWindow;

View File

@@ -0,0 +1,28 @@
import React from 'react';
import { Link } from 'react-router-dom';
function Navbar({ customerId }) {
return (
<nav class="navbar navbar-expand-lg navbar-light">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link"><Link style={{color: "white", textDecoration: "none"}} to={`/movie/${customerId}`}>Main Page</Link></a>
</li>
<li class="nav-item active">
<a class="nav-link"><Link style={{color: "white", textDecoration: "none"}} to={`/genre/${customerId}`}>Search Page</Link></a>
</li>
<li class="nav-item active">
<a class="nav-link"><Link style={{color: "white", textDecoration: "none"}} to={`/library/${customerId}`}>Library Page</Link></a>
</li>
<li class="nav-item active">
<a class="nav-link"><Link style={{color: "white", textDecoration: "none"}} to="/customer">Registration Page</Link></a>
</li>
</ul>
</nav>
);
}
export default Navbar;

View File

@@ -0,0 +1,30 @@
import React from "react";
let imgs = ['https://cdn-l-cyberpunk.cdprojektred.com/edgerunners/Cyberpunk-Edgerunners-S1-Poster-en.jpg',
'https://upload.wikimedia.org/wikipedia/ru/thumb/f/f2/%D0%90%D1%80%D0%BA%D0%B5%D0%B9%D0%BD_%28%D0%BC%D1%83%D0%BB%D1%8C%D1%82%D1%81%D0%B5%D1%80%D0%B8%D0%B0%D0%BB%29.jpg/800px-%D0%90%D1%80%D0%BA%D0%B5%D0%B9%D0%BD_%28%D0%BC%D1%83%D0%BB%D1%8C%D1%82%D1%81%D0%B5%D1%80%D0%B8%D0%B0%D0%BB%29.jpg',
'https://cdn.shopify.com/s/files/1/0106/3708/2686/collections/Collection_Image_2_600x600_crop_center.jpg?v=1643983621'
];
const SearchSuggestions = () =>
{
return (
<div className="flex-container" style={{display: "flex", flexDirection: "column", flex:"1" }}>
<header className="flex-item" style={{display: "flex", height: "90px"}}>
<div className="flex-itemB2 text-center align-self-center" style={{flex: "1", color: "white", fontSize: "32px", fontWeight: "bold"}}>You might like this</div>
</header>
<main style={{display: "flex", flex: "1", gap: "20px"}}>
<div className="flex-containerB3" style={{flex: "1", flexDirection: "column", display: "flex", marginLeft: "20px"}}>
<div className="flex-itemB31" style={{flex: "10"}}><img src={imgs[0]} alt = "cover1" width="100%" height="100%"/></div>
<div className="flex-itemB32 text-center" style={{flex: "1", color:"white",fontSize: " 32px",fontWeight: "bold"}}>Cyberpunk: Edgerunners</div>
</div>
<div className="flex-containerB4" style={{flex: "1", flexDirection: "column", display: "flex"}}>
<div className="flex-itemB41" style={{flex: "10"}}><img src={imgs[1]} alt="cover2" width="100%" height="100%"/></div>
<div className="flex-itemB42 text-center" style={{flex: "1", color:"white",fontSize: " 32px",fontWeight: "bold"}}>Arcane</div>
</div>
<div className="flex-containerB5" style={{flex: "1", flexDirection: "column", display: "flex", marginRight: "20px"}}>
<div className="flex-itemB51" style={{flex: "10"}}><img src={imgs[2]} alt = "cover3" width="100%" height="100%"/></div>
<div className="flex-itemB52 text-center" style={{flex: "1", color:"white",fontSize: " 32px",fontWeight: "bold"}}>Stranger Things</div>
</div>
</main>
</div>
);
}
export default SearchSuggestions;

View File

@@ -0,0 +1,112 @@
import React,{useEffect,useState} from "react";
import { useParams } from 'react-router-dom';
import gradientImg from '../Assets/background.png';
import Navbar from '../Components/Navbar';
import Footer from '../Components/Footer';
import { getMovie } from "../Components/DataService";
import { Button, Modal } from "react-bootstrap";
import { updateMovie } from "../Components/DataService";
function Filmpage()
{
const { customerId, movieId } = useParams();
const [movie, setMovie] = useState(null);
const [showModal, setShowModal] = useState(false);
const [modalData, setModalData] = useState({
title: "",
score: "",
length: "",
});
useEffect(() => {
fetchMovie();
}, []);
const fetchMovie = async () => {
const movieData = await getMovie(movieId);
setMovie(movieData);
};
const handleModalOpen = () => {
setShowModal(true);
};
const handleModalClose = () => {
setShowModal(false);
setModalData({
title: "",
score: "",
length: "",
});
};
const handleModalInputChange = (event) => {
const { name, value } = event.target;
setModalData((prevData) => ({
...prevData,
[name]: value,
}));
};
const handleModalSubmit = async () => {
await updateMovie(movieId, modalData);
fetchMovie();
handleModalClose();
};
if (!movie) {
return <p>Loading movie...</p>;
}
return(
<body>
<div className="flex-container" style={{flexDirection:"column",display: "flex",backgroundImage: `url(${gradientImg})`}}>
<Navbar customerId={customerId}/>
<div className="flex-container min-vh-100" style={{flexDirection: "column", display: "flex"}}>
<main style={{display: "flex", flex: "1", gap:"100px"}}>
<div className="flex-container" style={{display: "inline-flex", flex:"1" , flexWrap:" wrap", gap: "40px"}}>
<div className="flex-item1 align-self-center" style={{ flex:"1"}}>
<img src="https://www.seekpng.com/png/detail/8-84931_question-mark-question-mark-white-background.png" width="400px" height="600px"/></div>
<div className="flex-container align-self-center" style={{flex: "3"}}>
<div className="flex-item1 text-light" style={{fontSize: "50px"}}><a>{movie.title}</a></div>
<div className="flex-item3 text-light" style={{fontSize: "35px"}}>Average score: {movie.score}</div>
<div className="flex-item3 text-light" style={{fontSize: "35px"}}>Length: {movie.length}</div>
<div className="flex-item3 text-light" style={{fontSize: "35px"}}>Genre: {movie.genreName}</div>
<button className="primary" onClick={handleModalOpen}>Edit Movie</button>
</div>
</div>
</main>
</div>
<Footer/>
<Modal show={showModal} onHide={handleModalClose}>
<Modal.Header closeButton>
<Modal.Title>Edit Movie</Modal.Title>
</Modal.Header>
<Modal.Body>
<div className="form-group">
<label>Title:</label>
<input type="text" className="form-control" name="title" value={modalData.title} onChange={handleModalInputChange} />
</div>
<div className="form-group">
<label>Score:</label>
<input type="text" className="form-control" name="score" value={modalData.score} onChange={handleModalInputChange} />
</div>
<div className="form-group">
<label>Length:</label>
<input type="text" className="form-control" name="length" value={modalData.length} onChange={handleModalInputChange} />
</div>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleModalClose}>Close</Button>
<Button variant="primary" onClick={handleModalSubmit}>Save Changes</Button>
</Modal.Footer>
</Modal>
</div>
</body>
)
}
export default Filmpage;

View File

@@ -0,0 +1,63 @@
import React,{useEffect,useState} from "react";
import gradientImg from '../Assets/background.png';
import Footer from '../Components/Footer';
import Navbar from '../Components/Navbar';
import Film from "../Components/Film";
import { useParams} from 'react-router-dom';
import { getCustomerMovies } from "../Components/DataService";
import { removeCustomerMovie } from "../Components/DataService";
function Librarypage()
{
const [movies, setMovies] = useState([]);
const { customerId } = useParams();
useEffect(() => {
const params = new URLSearchParams(location.search);
const token = params.get('token');
fetchMovies();
}, []);
const fetchMovies = async () => {
const moviesData = await getCustomerMovies(token);
console.log(moviesData);
setMovies(moviesData);
};
const handleDeleteMovie = async (movieId) => {
await removeCustomerMovie(movieId,token);
fetchMovies();
}
return(
<div style={{backgroundImage: `url(${gradientImg})`}}>
<Navbar customerId={customerId}/>
<div className="flex-container min-vh-100" style={{display: "flex", marginLeft:"20px",marginTop:"50px"}}>
{movies.length > 0 ? (
<div style={{flexDirection: "row", display:"flex",flexWrap: "wrap",gap:"30px"}}>
{movies.map((movie) => (
<Film key={movie.id}
title={movie.title}
main={false}
acquire={() => handleDeleteMovie(movie.id)}
movieId = {movie.id}
customerId={customerId}
/>
))}
</div>
) : (
<h1 style={{color:"white"}}>No movies available</h1>
)}
</div>
<Footer/>
</div>
)
}
export default Librarypage;

View File

@@ -0,0 +1,48 @@
import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import gradientImg from '../Assets/background.png';
import { fillRepos } from '../Components/DataService';
import {loginUser} from '../Components/DataService';
function Loginpage() {
const navigate = useNavigate();
const handleLogin = () => {
const userId = loginUser(document.getElementById("username").value,document.getElementById("password").value)
fillRepos();
navigate(`/movie/${userId}`);
};
return (
<div className="flex-container" style={{flexDirection:"column",display: "flex",backgroundImage: `url(${gradientImg})`}}>
<div className="flex-container min-vh-100" style={{flexDirection: "column", display: "flex", alignItems: "center", justifyContent: "center", gap: "20px"}}>
<form onSubmit={handleLogin}>
<div className="mb-3">
<input type="text" name="username" id="username" className="form-control"
placeholder="Login" required autoFocus />
</div>
<div className="mb-3">
<input type="password" name="password" id="password" className="form-control"
placeholder="Password" required />
</div>
<button type="submit" className="btn btn-success button-fixed">Login</button>
<a className="btn btn-primary button-fixed" href="/">Registration</a>
</form>
</div>
</div>
);
}
export default Loginpage;

View File

@@ -0,0 +1,73 @@
import React, { useEffect, useState } from 'react';
import gradientImg from '../Assets/background.png';
import Footer from '../Components/Footer';
import { getMovies } from '../Components/DataService';
import { acquireMovie } from '../Components/DataService';
import { deleteMovie } from '../Components/DataService';
import { useParams} from 'react-router-dom';
import Navbar from '../Components/Navbar';
import Film from '../Components/Film';
function MainPage() {
const [movies, setMovies] = useState([]);
const { customerId } = useParams();
useEffect(() => {
const params = new URLSearchParams(location.search);
const token = params.get('token');
fetchMovies();
}, []);
const fetchMovies = async () => {
const moviesData = await getMovies();
console.log(moviesData);
setMovies(moviesData);
};
const handleAcquireMovie = async (movieId) => {
await acquireMovie(movieId,token);
const updatedMovies = movies.map((movie) => {
return movie;
});
setMovies(updatedMovies);
};
const handleDeleteMovie = async (movieId) => {
await deleteMovie(movieId,token);
}
return (
<div style={{backgroundImage: `url(${gradientImg})`}}>
<Navbar customerId={customerId}/>
<div className="flex-container min-vh-100" style={{flexDirection: "row", display: "flex", marginLeft:"20px",marginTop:"50px"}}>
{movies.length > 0 ? (
<div style={{flexDirection: "row", display:"flex",flexWrap: "wrap",justifyContent:"space-between"}}>
{movies.map((movie) => (
<Film key={movie.id}
title={movie.title}
acquire={() => handleAcquireMovie(movie.id)}
main = {true}
movieId = {movie.id}
customerId={customerId}
/>
))}
</div>
) : (
<h1 style={{color: "white"}}>No movies available</h1>
)}
</div>
<Footer/>
</div>
);
}
export default MainPage;

View File

@@ -0,0 +1,86 @@
import React,{useState} from 'react';
import { useNavigate } from 'react-router-dom';
import { registerUser } from '../Components/DataService.js';
import gradientImg from '../Assets/background.png';
import CoverImg from '../Assets/cover.png'
import Footer from '../Components/Footer';
function Regpage()
{
const [inputUsername, setUsername] = useState('');
const [inputPassword,setPassword] = useState('');
const [inputRole,setRole] = useState('');
const navigate = useNavigate();
const handleInputChange = (e) => {
const {id , value} = e.target;
if(id === "inputUsername"){
setUsername(value);
}
if(id === "inputPassword"){
setPassword(value);
}
if(id === "inputRole"){
setRole(value);
}
}
const handleSubmit = async (event) => {
event.preventDefault();
if(inputRole === '')
{
setRole("USER");
}
const customerDTO = await registerUser(inputUsername, inputPassword,inputRole);
setUsername ('');
setPassword ('');
setRole ('');
navigate(`/login`);
}
return(
<div className="flex-container" style={{flexDirection:"column",display: "flex",backgroundImage: `url(${gradientImg})`}}>
<div className="flex-container min-vh-100" style={{flexDirection: "column", display: "flex"}}>
<main style={{display: "flex", flex: "1"}}>
<aside className="flex-item2" style={{flex: "2"}}></aside>
<div className="flex-item3 align-self-center" style={{flex: "3"}}><img src={CoverImg} alt = "cover" width="100%" height="600px"/></div>
<section className="flex-container align-self-center" style={{height:"660px", flex: "4", backgroundColor: "#ffd79d", flexDirection: "column", display: "flex"}}>
<form>
<section className="flex-itemR1" style={{color: "#320D3E",fontSize: "50px",fontWeight: "bold", paddingLeft: "30px",paddingTop: "10px"}}>SIGN UP</section>
<section className="flex-itemR2" style={{color: "#320D3E",fontSize: "35px",fontWeight: "bold", paddingLeft: "30px",paddingTop: "10px"}}>
<label style={{color: "#320D3E",fontSize: "32px",fontWeight: "bold"}}>USERNAME</label>
</section>
<section className="flex-itemR3" style={{display: "flex", width: "320px", paddingLeft: "30px"}}>
<input className="form-control" id="inputUsername" type="string" value={inputUsername} onChange = {(e) => handleInputChange(e)} placeholder="Enter username" required autoFocus maxLength={64}/>
</section>
<section className="flex-itemR6" style={{color: "#320D3E",fontSize: "35px",fontWeight: "bold", paddingLeft: "30px",paddingTop: "10px"}}>
<label style={{color: "#320D3E",fontSize: "32px",fontWeight: "bold"}}>PASSWORD</label>
</section>
<section className="flex-itemR7" style={{display: "flex", width: "320px", paddingLeft: "30px"}}>
<input className="form-control" id="inputPassword" type="password" value={inputPassword} onChange = {(e) => handleInputChange(e)} placeholder="Enter password" required minlength={6} maxlength={64}/>
</section>
<section class="flex-itemR8" style={{display: "flex", width: "320px", paddingLeft: "30px"}}>
<select id="inputRole" required onChange = {(e) => handleInputChange(e)}>
<option value="nothing"></option>
<option value="USER">USER</option>
<option value="ADMIN">ADMIN</option>
</select>
</section>
<button className="btn btn-primary" type="submit" id="register" style={{fontSize: "20px", marginLeft: "30px", marginTop: "15px", width: "150px", backgroundColor: "#320D3E", color:"white", fontWeight: "bold"}} onClick={(e)=>handleSubmit(e)} >Register</button>
<a href="/login">Sign in</a>
</form>
</section>
<aside className="flex-item5" style={{flex: "2"}}></aside>
</main>
</div>
<Footer/>
</div>
)
}
export default Regpage;

View File

@@ -0,0 +1,85 @@
import React,{useState,useEffect} from "react";
import gradientImg from '../Assets/background.png'
import Navbar from '../Components/Navbar';
import Footer from '../Components/Footer'
import Film from '../Components/Film';
import { getMoviesByGenre } from "../Components/DataService";
import { useParams } from 'react-router-dom';
import { getGenres } from "../Components/DataService";
function Searchpage()
{
const { customerId } = useParams();
const [genres, setGenres] = useState([]);
const [movies, setMovies] = useState([]);
const [selectedGenre, setSelectedGenre] = useState('');
const [loading, setLoading] = useState(false);
useEffect(() => {
fetchGenres();
}, []);
const fetchGenres = async() =>{
const response = await getGenres();
setGenres(response);
}
const handleGenreChange = (event) => {
setSelectedGenre(event.target.value);
};
const handleSearch = async () => {
setLoading(true);
const response = await getMoviesByGenre(selectedGenre);
setLoading(false);
setMovies(response);
}
return (
<div className="flex-container" style={{ flexDirection: "column", display: "flex", backgroundImage: `url(${gradientImg})` }}>
<Navbar customerId={customerId} />
<div className="flex-container min-vh-100" style={{ flexDirection: "column", display: "flex", flex: "1", alignItems: "center", justifyContent: "flex-start", marginTop: "20px" }}>
<div>
<select id="genre-select" value={selectedGenre} onChange={handleGenreChange}>
<option value="all">All Genres</option>
{genres.map((genre) => (
<option key={genre.id} value={genre.name}>
{genre.name}
</option>
))}
</select>
<button type="button" onClick={handleSearch}>Search</button>
</div>
<div className="flex-container min-vh-100" style={{flexDirection: "row", display: "flex", marginLeft:"20px",marginTop:"50px"}}>
{loading ? (
<p>Loading movies...</p>
) : (
<div style={{flexDirection: "row", display:"flex",flexWrap: "wrap",gap:"30px"}}>
{movies.length > 0 ? (
movies.map((movie) => (
<Film
key={movie.id}
title={movie.title}
movieId={movie.id}
customerId={customerId}
/>
))
) : (
<h1 style={{color:"white"}}>No movies found</h1>
)}
</div>
)}
</div>
</div>
<Footer/>
</div>
);
}
export default Searchpage;

13
frontend/src/index.css Normal file
View File

@@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

17
frontend/src/index.js Normal file
View File

@@ -0,0 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<App />
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@@ -0,0 +1,13 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

23
frontend/src/style.css Normal file
View File

@@ -0,0 +1,23 @@
@media screen and (max-width: 768px) {
main
{
flex-direction: column;
flex-wrap: nowrap;
}
header
{
flex-direction: column;
}
}
.button:hover
{
background-color: #ffd79d;
color:black;
}

View File

@@ -0,0 +1,63 @@
package ru.ulstu.is.sbapp.Customer.Controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import ru.ulstu.is.sbapp.WebConfiguration;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping(WebConfiguration.REST_API + "/customer")
public class CustomerController {
public static final String URL_LOGIN = "/login";
private final CustomerService customerService;
public CustomerController(CustomerService customerService)
{
this.customerService = customerService;
}
@PostMapping(URL_LOGIN)
public String login(@RequestBody @Valid CustomerDTO customerDTO) {
return customerService.loginAndGetToken(customerDTO);
}
@GetMapping("/{id}")
public CustomerDTO getCustomer(@PathVariable Long id) {
return new CustomerDTO(customerService.findCustomer(id));
}
@GetMapping
public List<CustomerDTO> getCustomers() {
return customerService.findAllCustomers().stream().map(CustomerDTO::new).toList();
}
@PostMapping
public CustomerDTO createCustomer(@RequestParam("fullName") String fullName, @RequestParam("password") String password, @RequestParam("role") String role) {
return new CustomerDTO(customerService.createUser(fullName,password,CustomerRole.valueOf(role)));
}
@PutMapping("/{id}")
public CustomerDTO updateCustomer(@PathVariable Long id, @RequestParam("fullName") String fullName) {
return new CustomerDTO(customerService.updateCustomer(id,fullName));
}
@DeleteMapping("/{id}")
public CustomerDTO deleteCustomer(@PathVariable Long id) {
return new CustomerDTO(customerService.deleteCustomer(id));
}
@GetMapping("/movies")
public List<MovieDTO> getCustomerMovies(@RequestParam("token") String token) {
String username = customerService.loadUserByToken(token).getUsername();
return customerService.findCustomerMovies(customerService.findByLogin(username).getId()).stream()
.map(MovieDTO::new)
.toList();
}
}

View File

@@ -0,0 +1,48 @@
package ru.ulstu.is.sbapp.Customer.Controller;
import com.fasterxml.jackson.annotation.JsonProperty;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import java.util.List;
public class CustomerDTO {
public long id;
public String username;
public String password;
public CustomerRole role;
public List<MovieDTO> movies;
public CustomerDTO() {
}
public CustomerDTO(Customer customer) {
this.id = customer.getId();
this.username = customer.getUsername();
this.password = customer.getPassword();
this.role = customer.getRole();
this.movies = customer.getMovies().stream().map(MovieDTO::new).toList();
}
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public long getID() {
return id;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public CustomerRole getRole() {
return role;
}
public List<MovieDTO> getMovies() {
return movies;
}
}

View File

@@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.Customer.Exception;
public class CustomerExistsException extends RuntimeException{
public CustomerExistsException(String login) {
super(String.format("Customer '%s' already exists", login));
}
}

View File

@@ -0,0 +1,10 @@
package ru.ulstu.is.sbapp.Customer.Exception;
public class CustomerNotFoundException extends RuntimeException{
public CustomerNotFoundException(Long id){
super(String.format("Customer with id [%s] is not found", id));
}
public CustomerNotFoundException(String username) {
super(String.format("Customer is not found '%s'", username));
}
}

View File

@@ -0,0 +1,84 @@
package ru.ulstu.is.sbapp.Customer.Model;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
@Entity
public class Customer
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false, unique = true, length = 64)
@NotBlank(message = "Username can't be null or empty")
@Size(min = 3, max = 64)
private String username;
@Column(nullable = false, length = 64)
@NotBlank(message = "Password can't be empty")
@Size(min = 6, max = 64)
private String password;
private CustomerRole role;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Movie> movies;
public Customer()
{
}
public Customer(String username,String password,CustomerRole role)
{
this.username = username;
this.password = password;
this.role = role;
this.movies = new ArrayList<>();
}
public Long getId()
{
return id;
}
public String getPassword() {return password;}
public String getUsername()
{
return username;
}
public CustomerRole getRole() {
return role;
}
public void setUsername(String username)
{
this.username = username;
}
public List<Movie> getMovies()
{
return movies;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return Objects.equals(id, customer.id);
}
@Override
public String toString()
{
return "Customer: " + "ID: " + id + " | Username: " + username;
}
}

View File

@@ -0,0 +1,20 @@
package ru.ulstu.is.sbapp.Customer.Model;
import org.springframework.security.core.GrantedAuthority;
public enum CustomerRole implements GrantedAuthority {
ADMIN,
USER;
private static final String PREFIX = "ROLE_";
@Override
public String getAuthority() {
return PREFIX + this.name();
}
public static final class AsString {
public static final String ADMIN = PREFIX + "ADMIN";
public static final String USER = PREFIX + "USER";
}
}

View File

@@ -0,0 +1,8 @@
package ru.ulstu.is.sbapp.Customer.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
public interface CustomerRepository extends JpaRepository<Customer, Long> {
Customer findOneByUsernameIgnoreCase(String login);
}

View File

@@ -0,0 +1,147 @@
package ru.ulstu.is.sbapp.Customer.Service;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Customer.Controller.CustomerDTO;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerExistsException;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
import ru.ulstu.is.sbapp.Customer.Repository.CustomerRepository;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import ru.ulstu.is.sbapp.Utilities.validation.ValidationException;
import ru.ulstu.is.sbapp.Utilities.validation.ValidatorUtil;
import ru.ulstu.is.sbapp.jwt.JwtException;
import ru.ulstu.is.sbapp.jwt.JwtProvider;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Service
public class CustomerService implements UserDetailsService
{
private final CustomerRepository customerRepository;
private final PasswordEncoder passwordEncoder;
private final ValidatorUtil validatorUtil;
private final JwtProvider jwtProvider;
public CustomerService(CustomerRepository customerRepository, PasswordEncoder passwordEncoder,
ValidatorUtil validatorUtil,
JwtProvider jwtProvider) {
this.customerRepository = customerRepository;
this.validatorUtil = validatorUtil;
this.passwordEncoder = passwordEncoder;
this.jwtProvider = jwtProvider;
}
public Customer findByLogin(String login) {
return customerRepository.findOneByUsernameIgnoreCase(login);
}
public Customer createUser(String login, String password, CustomerRole role) {
if (findByLogin(login) != null) {
throw new CustomerExistsException(login);
}
final Customer user = new Customer(login, passwordEncoder.encode(password), role);
validatorUtil.validate(user);
return customerRepository.save(user);
}
public String loginAndGetToken(CustomerDTO customerDTO) {
final Customer customer = findByLogin(customerDTO.getUsername());
if (customer == null) {
throw new CustomerNotFoundException(customerDTO.getUsername());
}
if (!passwordEncoder.matches(customerDTO.getPassword(), customer.getPassword())) {
throw new CustomerNotFoundException(customer.getUsername());
}
return jwtProvider.generateToken(customer.getUsername());
}
public UserDetails loadUserByToken(String token) throws UsernameNotFoundException {
if (!jwtProvider.isTokenValid(token)) {
throw new JwtException("Bad token");
}
final String userLogin = jwtProvider.getLoginFromToken(token)
.orElseThrow(() -> new JwtException("Token is not contain Login"));
return loadUserByUsername(userLogin);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
final Customer userEntity = findByLogin(username);
if (userEntity == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(
userEntity.getUsername(), userEntity.getPassword(), Collections.singleton(userEntity.getRole()));
}
@Transactional(readOnly = true)
public Customer findCustomer(Long id)
{
final Optional<Customer> student = customerRepository.findById(id);
return student.orElseThrow(() -> new CustomerNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Customer> findAllCustomers()
{
return customerRepository.findAll();
}
@Transactional
public Customer updateCustomer(Long id, String fullName)
{
if(!StringUtils.hasText(fullName))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
final Optional<Customer> customer = customerRepository.findById(id);
if(customer.isEmpty())
{
throw new CustomerNotFoundException(id);
}
final Customer specificCustomer = customer.get();
specificCustomer.setUsername(fullName);
validatorUtil.validate(specificCustomer);
return customerRepository.save(specificCustomer);
}
@Transactional
public Customer deleteCustomer(Long id)
{
final Optional<Customer> customer = customerRepository.findById(id);
if(customer.isEmpty())
{
throw new CustomerNotFoundException(id);
}
final Customer specificCustomer = customer.get();
customerRepository.delete(specificCustomer);
return specificCustomer;
}
@Transactional
public void deleteAllCustomers()
{
customerRepository.deleteAll();
}
@Transactional(readOnly = true)
public List<Movie> findCustomerMovies(Long customerId){
final Optional<Customer> customer = customerRepository.findById(customerId);
return customer.get().getMovies();
}
}

View File

@@ -0,0 +1,48 @@
package ru.ulstu.is.sbapp.Genre.Controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
import ru.ulstu.is.sbapp.WebConfiguration;
import java.util.List;
@RestController
@RequestMapping(WebConfiguration.REST_API + "/genre")
@ControllerAdvice(annotations = RestController.class)
public class GenreController {
private final GenreService genreService;
public GenreController(GenreService genreService) {
this.genreService = genreService;
}
@GetMapping("/{id}")
public GenreDTO getGenre(@PathVariable Long id) {
return new GenreDTO(genreService.findGenre(id));
}
@GetMapping
public List<GenreDTO> getGenres() {
return genreService.findAllGenres().stream()
.map(GenreDTO::new)
.toList();
}
@PostMapping
public GenreDTO createGenre(@RequestParam("name") String name) {
return new GenreDTO(genreService.addGenre(name));
}
@PutMapping("/{id}")
public GenreDTO updateGenre(@PathVariable Long id,
@RequestParam("name") String name) {
return new GenreDTO(genreService.updateGenre(id,name));
}
@DeleteMapping("/{id}")
public GenreDTO deleteGenre(@PathVariable Long id) {
return new GenreDTO(genreService.deleteGenre(id));
}
@PostMapping("/fill")
public boolean insertGenres() { return genreService.fillRepo();}
}

View File

@@ -0,0 +1,32 @@
package ru.ulstu.is.sbapp.Genre.Controller;
import com.fasterxml.jackson.annotation.JsonProperty;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import java.util.List;
public class GenreDTO {
private final Long id;
private final String name;
private final List<MovieDTO> movies;
public GenreDTO(Genre genre) {
this.id = genre.getId();
this.name = genre.getName();
this.movies = genre.getMovies().stream().map(MovieDTO::new).toList();
}
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public long getID() {
return id;
}
public String getName() {
return name;
}
public List<MovieDTO> getMovies() {
return movies;
}
}

View File

@@ -0,0 +1,11 @@
package ru.ulstu.is.sbapp.Genre.Exception;
public class GenreNotFoundException extends RuntimeException{
public GenreNotFoundException(Long id){
super(String.format("Genre with id [%s] is not found", id));
}
public GenreNotFoundException(String name){
super(String.format("Genre with name [%s] is not found", name));
}
}

View File

@@ -1,6 +1,9 @@
package ru.ulstu.is.sbapp.Models;
package ru.ulstu.is.sbapp.Genre.Model;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -11,10 +14,11 @@ public class Genre
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
@Column
@NotBlank(message = "Genre's can't be null or empty")
private String name;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "genre")
@OneToMany(fetch = FetchType.EAGER, mappedBy = "genre", cascade = CascadeType.ALL)
private List<Movie> movies;
public Genre()

View File

@@ -0,0 +1,15 @@
package ru.ulstu.is.sbapp.Genre.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import java.util.List;
import java.util.Optional;
public interface GenreRepository extends JpaRepository<Genre,Long> {
Optional<Genre> findByNameLike(String genreName);
}

View File

@@ -0,0 +1,120 @@
package ru.ulstu.is.sbapp.Genre.Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Customer.Repository.CustomerRepository;
import ru.ulstu.is.sbapp.Genre.Exception.GenreNotFoundException;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Repository.GenreRepository;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import ru.ulstu.is.sbapp.Utilities.validation.ValidatorUtil;
import java.util.List;
import java.util.Optional;
@Service
public class GenreService
{
private final GenreRepository genreRepository;
private final ValidatorUtil validatorUtil;
public GenreService(GenreRepository genreRepository, ValidatorUtil validatorUtil) {
this.genreRepository = genreRepository;
this.validatorUtil = validatorUtil;
}
@Transactional
public Genre addGenre(String name) {
if(!StringUtils.hasText(name))
{
throw new IllegalArgumentException("Genre's name is missing");
}
final Genre genre = new Genre(name);
validatorUtil.validate(genre);
return genreRepository.save(genre);
}
@Transactional(readOnly = true)
public Genre findGenre(Long id) {
final Optional<Genre> genre = genreRepository.findById(id);
return genre.orElseThrow(() -> new GenreNotFoundException(id));
}
@Transactional(readOnly = true)
public Genre findGenreByName(String name)
{
final Optional<Genre> genre = genreRepository.findByNameLike(name);
return genre.orElseThrow(() -> new GenreNotFoundException(name));
}
@Transactional(readOnly = true)
public List<Genre> findAllGenres()
{
return genreRepository.findAll();
}
@Transactional
public Genre updateGenre(Long id, String name) {
if(!StringUtils.hasText(name))
{
throw new IllegalArgumentException("Genre's name is missing");
}
final Optional<Genre> genre = genreRepository.findById(id);
if(genre.isEmpty())
{
throw new GenreNotFoundException(id);
}
Genre specificGenre = genre.get();
specificGenre.setName(name);
validatorUtil.validate(genre);
return genreRepository.save(specificGenre);
}
@Transactional
public Genre deleteGenre(Long id) {
final Optional<Genre> genre = genreRepository.findById(id);
if(genre.isEmpty())
{
throw new GenreNotFoundException(id);
}
Genre specificGenre = genre.get();
specificGenre.getMovies().clear();
genreRepository.delete(specificGenre);
return specificGenre;
}
@Transactional
public void deleteAllGenres() {
genreRepository.deleteAll();
}
public boolean fillRepo()
{
if(genreRepository.count() != 0)
{
return false;
}
Genre genreSciFi = addGenre("Sci-Fi");
Genre genreAdventure = addGenre("Adventure");
Genre genreAction = addGenre("Action");
Genre genreComedy = addGenre("Comedy");
return true;
}
}

View File

@@ -1,102 +0,0 @@
package ru.ulstu.is.sbapp.Models;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Entity
public class Customer
{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private String first_name;
@Column(nullable = false)
private String last_name;
@Column()
private String middle_name;
@OneToMany(fetch = FetchType.EAGER)
private List<Movie> movies;
public Customer()
{
}
public Customer(String fullName)
{
String[] partsName = fullName.split(" ");
this.first_name = partsName[0];
this.last_name = partsName[1];
if(partsName.length == 3)
{
this.middle_name = partsName[2];
}
this.movies = new ArrayList<>();
}
public Long getId()
{
return id;
}
public String getFirst_name()
{
return first_name;
}
public void setFirst_name(String fullName)
{
String[] partsName = fullName.split(" ");
this.first_name = partsName[0];
}
public String getLast_name()
{
return last_name;
}
public void setLast_name(String fullName)
{
String[] partsName = fullName.split(" ");
this.last_name = partsName[1];
}
public String getMiddle_name()
{
return middle_name.isBlank() ? null : middle_name;
}
public void setMiddle_name(String fullName)
{
String[] partsName = fullName.split(" ");
if(partsName.length == 3)
{
this.middle_name = partsName[2];
}
}
public List<Movie> getMovies()
{
return movies;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return Objects.equals(id, customer.id);
}
@Override
public String toString()
{
return "Customer: " + "ID: " + id + " | FirstName: " + first_name + " | LastName: " + last_name + " | MiddleName: " + middle_name;
}
}

View File

@@ -0,0 +1,82 @@
package ru.ulstu.is.sbapp.Movie.Controller;
import org.springframework.web.bind.annotation.*;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Model.CustomerRole;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import ru.ulstu.is.sbapp.Movie.Service.MovieService;
import ru.ulstu.is.sbapp.WebConfiguration;
import java.util.List;
@RestController
@RequestMapping(WebConfiguration.REST_API + "/movie")
@ControllerAdvice(annotations = RestController.class)
public class MovieController {
private final MovieService movieService;
private final CustomerService customerService;
public MovieController(MovieService movieService, CustomerService customerService) {
this.movieService = movieService;
this.customerService = customerService;
}
@GetMapping("/{id}")
public MovieDTO getMovie(@PathVariable Long id) {
return new MovieDTO(movieService.findMovie(id));
}
@GetMapping
public List<MovieDTO> getMovies() {
return movieService.findAllMovies().stream()
.map(MovieDTO::new)
.toList();
}
@GetMapping("/movies/{genre}")
public List<MovieDTO> getSpecificMovies(@PathVariable("genre") String genre) {
return movieService.findAllSpecificMovies(genre).stream()
.map(MovieDTO::new)
.toList();
}
@PostMapping
public MovieDTO createMovie(@RequestParam("title") String title, @RequestParam("length") int length, @RequestParam("score") double score, @RequestParam("genre") Long genreId) {
return new MovieDTO(movieService.addMovie(title,length,score,genreId));
}
@PutMapping("/{id}")
public MovieDTO updateMovie(@PathVariable("id") Long id,
@RequestParam("title") String title,@RequestParam("length") int length,@RequestParam("score") double score ) {
return new MovieDTO(movieService.updateMovie(id,title,length,score));
}
@DeleteMapping("/{id}")
public MovieDTO deleteMovie(@PathVariable("id") Long id,@RequestParam("token") String token) throws IllegalAccessException {
String username = customerService.loadUserByToken(token).getUsername();
Customer customer = customerService.findByLogin(username);
if(customer.getRole() != CustomerRole.ADMIN)
{
throw new IllegalAccessException("You don't have an access to do it");
}
return new MovieDTO(movieService.deleteMovie(id));
}
@PostMapping("/customer/movies/add/{id}")
public MovieDTO assignMovie(@RequestParam("token") String token, @PathVariable("id") Long id)
{
String username = customerService.loadUserByToken(token).getUsername();
return new MovieDTO(movieService.assignMovie(customerService.findByLogin(username).getId(),id));
}
@DeleteMapping("/customer/movies/delete/{id}")
public MovieDTO deleteMovieCustomer(@RequestParam("token") String token,@PathVariable("id") Long id) {
String username = customerService.loadUserByToken(token).getUsername();
return new MovieDTO(movieService.deleteMovieCustomer(id,customerService.findByLogin(username).getId()));
}
@PostMapping("/fill")
public boolean insertMovies()
{
return movieService.fillRepo();
}
}

View File

@@ -0,0 +1,38 @@
package ru.ulstu.is.sbapp.Movie.Controller;
import com.fasterxml.jackson.annotation.JsonProperty;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import java.util.List;
public class MovieDTO {
private final Long id;
private final String title;
private final int length;
private final double score;
private final String genreName;
public MovieDTO(Movie movie) {
this.id = movie.getId();
this.title = movie.getTitle();
this.length = movie.getLength();
this.score = movie.getScore();
this.genreName = movie.getGenre().getName();
}
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public long getID() {
return id;
}
public String getTitle() {
return title;
}
public int getLength() {
return length;
}
public double getScore() {
return score;
}
public String getGenreName() {return genreName;}
}

View File

@@ -0,0 +1,7 @@
package ru.ulstu.is.sbapp.Movie.Exception;
public class MovieNotFoundException extends RuntimeException{
public MovieNotFoundException(Long id){
super(String.format("Movie with id [%s] is not found", id));
}
}

View File

@@ -1,8 +1,10 @@
package ru.ulstu.is.sbapp.Models;
package ru.ulstu.is.sbapp.Movie.Model;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Objects;
@Entity
@@ -11,11 +13,14 @@ public class Movie
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
@Column
@NotBlank(message = "Movie's title can't be null or empty")
private String title;
@Column(nullable = false)
@Column
@NotNull(message = "Movie's length can't be null or empty")
private int length;
@Column(nullable = false)
@Column
@NotNull(message = "Movie's score can't be null or empty")
private double score;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "genre_fk")
@@ -49,9 +54,9 @@ public class Movie
this.title = title;
}
public String getLength()
public int getLength()
{
return Integer.toString(length);
return length;
}
public void setLength(int length)
@@ -59,9 +64,9 @@ public class Movie
this.length = length;
}
public String getScore()
public double getScore()
{
return Double.toString(score);
return score;
}
public void setScore(Double score)

View File

@@ -0,0 +1,14 @@
package ru.ulstu.is.sbapp.Movie.Repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import java.util.List;
public interface MovieRepository extends JpaRepository<Movie,Long> {
@Query("SELECT m FROM Movie m WHERE m.genre = :specGenre")
List<Movie> findByGenre(@Param("specGenre") Genre genre);
}

View File

@@ -0,0 +1,215 @@
package ru.ulstu.is.sbapp.Movie.Service;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Repository.CustomerRepository;
import ru.ulstu.is.sbapp.Genre.Exception.GenreNotFoundException;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Repository.GenreRepository;
import ru.ulstu.is.sbapp.Movie.Controller.MovieDTO;
import ru.ulstu.is.sbapp.Movie.Exception.MovieNotFoundException;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import ru.ulstu.is.sbapp.Movie.Repository.MovieRepository;
import ru.ulstu.is.sbapp.Utilities.validation.ValidatorUtil;
import javax.swing.text.html.Option;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@Service
public class MovieService
{
private final MovieRepository movieRepository;
private final GenreRepository genreRepository;
private final CustomerRepository customerRepository;
private final ValidatorUtil validatorUtil;
public MovieService(MovieRepository movieRepository, GenreRepository genreRepository, CustomerRepository customerRepository, ValidatorUtil validatorUtil) {
this.movieRepository = movieRepository;
this.validatorUtil = validatorUtil;
this.genreRepository = genreRepository;
this.customerRepository = customerRepository;
}
@Transactional
public Movie addMovie(String title, int length, double score, Long genre)
{
if(!StringUtils.hasText(title) || length == 0 || score == 0 || genre == 0)
{
throw new IllegalArgumentException("Some of the movie's properties are incorrect.");
}
final Optional<Genre> specGenre = genreRepository.findById(genre);
if(specGenre.isEmpty())
{
throw new GenreNotFoundException(genre);
}
final Movie movie = new Movie(title,length,score,specGenre.get());
validatorUtil.validate(movie);
specGenre.get().getMovies().add(movie);
return movieRepository.save(movie);
}
@Transactional
public Movie assignMovie(Long customerId, Long movieId)
{
if(customerId == 0 || movieId == 0)
{
throw new IllegalArgumentException("Some of the properties are incorrect.");
}
final Optional<Customer> specCustomer = customerRepository.findById(customerId);
final Optional<Movie> specMovie = movieRepository.findById(movieId);
if(specCustomer.get().getMovies().contains(specMovie.get()))
{
throw new IllegalArgumentException("You already have this movie");
}
specCustomer.get().getMovies().add(specMovie.get());
return specMovie.get();
}
@Transactional(readOnly = true)
public Movie findMovie(Long id)
{
final Optional<Movie> movie = movieRepository.findById(id);
return movie.orElseThrow(() -> new MovieNotFoundException(id));
}
@Transactional(readOnly = true)
public List<Movie> findAllMovies()
{
return movieRepository.findAll();
}
@Transactional
public Movie updateMovie(Long id, String title, int length, double score)
{
if(!StringUtils.hasText(title) && length == 0 && score == 0)
{
throw new IllegalArgumentException("Nothing to change.");
}
final Optional<Movie> movie = movieRepository.findById(id);
if(movie.isEmpty())
{
throw new MovieNotFoundException(id);
}
Movie specificMovie = movie.get();
Genre specificGenre = movie.get().getGenre();
if(length != 0)
{
specificMovie.setLength(length);
}
if(StringUtils.hasText(title))
{
specificMovie.setTitle(title);
}
if(score != 0)
{
specificMovie.setScore(score);
}
specificMovie.setGenre(specificGenre);
return movieRepository.save(specificMovie);
}
@Transactional
public Movie deleteMovieCustomer(Long id, Long customerId)
{
final Optional<Movie> movie = movieRepository.findById(id);
if(movie.isEmpty())
{
throw new MovieNotFoundException(id);
}
Movie specificMovie = movie.get();
specificMovie.getGenre().getMovies().remove(specificMovie);
final Optional<Customer> customer = customerRepository.findById(customerId);
if(customer.isEmpty())
{
throw new CustomerNotFoundException(id);
}
customer.get().getMovies().remove(specificMovie);
return specificMovie;
}
@Transactional
public Movie deleteMovie(Long id)
{
final Optional<Movie> movie = movieRepository.findById(id);
if(movie.isEmpty())
{
throw new MovieNotFoundException(id);
}
Movie specificMovie = movie.get();
specificMovie.getGenre().getMovies().remove(specificMovie);
final List<Customer> customers = customerRepository.findAll();
customers.forEach(customer -> {
customer.getMovies().remove(specificMovie);
});
movieRepository.delete(specificMovie);
return specificMovie;
}
@Transactional
public List<Movie> findAllSpecificMovies(String genreName)
{
return movieRepository.findByGenre(genreRepository.findByNameLike(genreName).get());
}
@Transactional
public void deleteAllMovies()
{
movieRepository.deleteAll();
}
public boolean fillRepo()
{
if(movieRepository.count() != 0)
{
return false;
}
Optional<Genre> genreSciFi = genreRepository.findByNameLike("Sci-Fi");
Optional<Genre> genreAdventure = genreRepository.findByNameLike("Adventure");
Optional<Genre> genreAction = genreRepository.findByNameLike("Action");
Optional<Genre> genreComedy = genreRepository.findByNameLike("Comedy");
Movie interstellar = addMovie("Interstellar",12,4.5,genreSciFi.get().getId());
Movie passengers = addMovie("Passengers",5,5.0,genreSciFi.get().getId());
Movie indianaJones = addMovie("Indiana Jones",9,4.3,genreAdventure.get().getId());
Movie jumandji = addMovie("Djumandji",2,3.1,genreAdventure.get().getId());
Movie fastFurious = addMovie("Fast and Furious 2",4,4.1,genreAction.get().getId());
Movie idk = addMovie("IDK",1,2.1,genreAction.get().getId());
Movie misterBean = addMovie("Mister bean in London",3,4.4,genreComedy.get().getId());
Movie ted = addMovie("TED",5,5.0,genreComedy.get().getId());
return true;
}
}

View File

@@ -0,0 +1,29 @@
package ru.ulstu.is.sbapp;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import ru.ulstu.is.sbapp.jwt.JwtFilter;
@Configuration
public class OpenAPI30Configuration {
public static final String API_PREFIX = "/api/1.0";
@Bean
public OpenAPI customizeOpenAPI() {
final String securitySchemeName = JwtFilter.TOKEN_BEGIN_STR;
return new OpenAPI()
.addSecurityItem(new SecurityRequirement()
.addList(securitySchemeName))
.components(new Components()
.addSecuritySchemes(securitySchemeName, new SecurityScheme()
.name(securitySchemeName)
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")));
}
}

View File

@@ -0,0 +1,14 @@
package ru.ulstu.is.sbapp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class PassowrdEncoderConfiguration {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

View File

@@ -2,10 +2,11 @@ package ru.ulstu.is.sbapp;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class SbappApplication {
public static void main(String[] args) {

View File

@@ -0,0 +1,61 @@
package ru.ulstu.is.sbapp;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import ru.ulstu.is.sbapp.Customer.Controller.CustomerController;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import ru.ulstu.is.sbapp.jwt.JwtFilter;
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
public static final String SPA_URL_MASK = "/{path:[^\\.]*}";
private final CustomerService customerService;
private final JwtFilter jwtFilter;
public SecurityConfiguration(CustomerService customerService) {
this.customerService = customerService;
this.jwtFilter = new JwtFilter(customerService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/", SPA_URL_MASK).permitAll()
.antMatchers(HttpMethod.POST, WebConfiguration.REST_API + "/customer" + CustomerController.URL_LOGIN).permitAll()
.antMatchers(HttpMethod.POST, WebConfiguration.REST_API + "/customer").permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.anonymous();
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception {
builder.userDetailsService(customerService);
}
@Override
public void configure(WebSecurity web) {
web
.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/**/*.{js,html,css,png}")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/webjars/**")
.antMatchers("/swagger-resources/**")
.antMatchers("/v3/api-docs/**");
}
}

View File

@@ -1,75 +0,0 @@
package ru.ulstu.is.sbapp.Services;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Models.Customer;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import java.util.List;
@Service
public class CustomerService
{
@PersistenceContext
private EntityManager em;
@Transactional
public Customer addCustomer(String fullName)
{
if(!StringUtils.hasText(fullName))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
final Customer customer = new Customer(fullName);
em.persist(customer);
return customer;
}
@Transactional(readOnly = true)
public Customer findCustomer(Long id)
{
final Customer customer = em.find(Customer.class,id);
if(customer == null)
{
throw new EntityNotFoundException(String.format("Customer with id [%s] is not found", id));
}
return customer;
}
@Transactional(readOnly = true)
public List<Customer> findAllCustomers()
{
return em.createQuery("select c from Customer c",Customer.class).getResultList();
}
@Transactional
public Customer updateCustomer(Long id, String fullName)
{
if(!StringUtils.hasText(fullName))
{
throw new IllegalArgumentException("Customer's name or surname is missing");
}
final Customer specificCustomer = findCustomer(id);
specificCustomer.setFirst_name(fullName);
specificCustomer.setLast_name(fullName);
specificCustomer.setMiddle_name(fullName);
return em.merge(specificCustomer);
}
@Transactional
public Customer deleteCustomer(Long id)
{
final Customer specificCustomer = findCustomer(id);
em.remove(specificCustomer);
return specificCustomer;
}
@Transactional
public void deleteAllCustomers()
{
em.createQuery("delete from Customer").executeUpdate();
}
}

View File

@@ -1,73 +0,0 @@
package ru.ulstu.is.sbapp.Services;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Models.Genre;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import java.util.List;
@Service
public class GenreService
{
@PersistenceContext
private EntityManager em;
@Transactional
public Genre addGenre(String name)
{
if(!StringUtils.hasText(name))
{
throw new IllegalArgumentException("Genre's name is missing");
}
final Genre genre = new Genre(name);
em.persist(genre);
return genre;
}
@Transactional(readOnly = true)
public Genre findGenre(Long id)
{
final Genre specificGenre = em.find(Genre.class,id);
if(specificGenre == null)
{
throw new EntityNotFoundException(String.format("Genre with id [%s] is not found", id));
}
return specificGenre;
}
@Transactional(readOnly = true)
public List<Genre> findAllGenres()
{
return em.createQuery("select g from Genre g",Genre.class).getResultList();
}
@Transactional
public Genre updateGenre(Long id, String name)
{
if(!StringUtils.hasText(name))
{
throw new IllegalArgumentException("Genre's name is missing");
}
final Genre specificGenre = findGenre(id);
specificGenre.setName(name);
return em.merge(specificGenre);
}
@Transactional
public Genre deleteGenre(Long id)
{
final Genre specificGenre = findGenre(id);
em.remove(specificGenre);
return specificGenre;
}
@Transactional
public void deleteAllGenres()
{
em.createQuery("delete from Genre").executeUpdate();
}
}

View File

@@ -1,89 +0,0 @@
package ru.ulstu.is.sbapp.Services;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import ru.ulstu.is.sbapp.Models.Movie;
import ru.ulstu.is.sbapp.Models.Customer;
import ru.ulstu.is.sbapp.Models.Genre;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import java.util.List;
@Service
public class MovieService
{
@PersistenceContext
private EntityManager em;
@Transactional
public Movie addMovie(String title, int length, double score, Genre genre, Customer customer)
{
if(!StringUtils.hasText(title) || length == 0 || score == 0 || genre == null || customer == null)
{
throw new IllegalArgumentException("Some of the movie's properties are incorrect.");
}
final Movie movie = new Movie(title,length,score,genre);
movie.getGenre().getMovies().add(movie);
customer.getMovies().add(movie);
em.persist(movie);
return movie;
}
@Transactional(readOnly = true)
public Movie findMovie(Long id)
{
final Movie specificMovie = em.find(Movie.class, id);
if(specificMovie == null)
{
throw new EntityNotFoundException(String.format("Movie with id [%s] is not found", id));
}
return specificMovie;
}
@Transactional(readOnly = true)
public List<Movie> findAllMovies()
{
return em.createQuery("select m from Movie m",Movie.class).getResultList();
}
@Transactional
public Movie updateMovie(Long id, String title, int length, double score, Genre genre)
{
if(!StringUtils.hasText(title) || length == 0 || score == 0 || genre == null)
{
throw new IllegalArgumentException("Some of the movie's properties are incorrect.");
}
final Movie specificMovie = findMovie(id);
specificMovie.setLength(length);
specificMovie.setGenre(genre);
specificMovie.setTitle(title);
specificMovie.setScore(score);
return em.merge(specificMovie);
}
@Transactional
public Movie deleteMovie(Long id, Customer customer)
{
final Movie specificMovie = findMovie(id);
specificMovie.getGenre().getMovies().remove(specificMovie);
customer.getMovies().remove(specificMovie);
em.remove(specificMovie);
return specificMovie;
}
@Transactional
public List<Movie> findAllSpecificMovies(Genre specGenre)
{
return em.createQuery("SELECT m FROM Movie m WHERE m.genre = :genre",Movie.class).setParameter("genre",specGenre).getResultList();
}
@Transactional
public void deleteAllMovies()
{
em.createQuery("delete from Movie").executeUpdate();
}
}

View File

@@ -0,0 +1,20 @@
package ru.ulstu.is.sbapp.Utilities;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
public class CookiesManagement {
public String GetUserID(HttpServletRequest request)
{
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("userID".equals(cookie.getName())) {
return cookie.getValue();
}
}
}
return null;
}
}

View File

@@ -0,0 +1,42 @@
package ru.ulstu.is.sbapp.Utilities.error;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
import ru.ulstu.is.sbapp.Genre.Exception.GenreNotFoundException;
import ru.ulstu.is.sbapp.Movie.Exception.MovieNotFoundException;
import ru.ulstu.is.sbapp.Utilities.validation.ValidationException;
import java.util.stream.Collectors;
@ControllerAdvice
public class AdviceController {
@ExceptionHandler({
MovieNotFoundException.class,
GenreNotFoundException.class,
CustomerNotFoundException.class,
ValidationException.class
})
public ResponseEntity<Object> handleException(Throwable e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Object> handleBindException(MethodArgumentNotValidException e) {
final ValidationException validationException = new ValidationException(
e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.toSet()));
return handleException(validationException);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleUnknownException(Throwable e) {
e.printStackTrace();
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}

View File

@@ -0,0 +1,12 @@
package ru.ulstu.is.sbapp.Utilities.validation;
import java.util.Set;
public class ValidationException extends RuntimeException {
public ValidationException(Set<String> errors) {
super(String.join("\n", errors));
}
public ValidationException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,30 @@
package ru.ulstu.is.sbapp.Utilities.validation;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;
import java.util.stream.Collectors;
@Component
public class ValidatorUtil {
private final Validator validator;
public ValidatorUtil() {
try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
this.validator = factory.getValidator();
}
}
public <T> void validate(T object) {
final Set<ConstraintViolation<T>> errors = validator.validate(object);
if (!errors.isEmpty()) {
throw new ValidationException(errors.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toSet()));
}
}
}

View File

@@ -1,11 +1,29 @@
package ru.ulstu.is.sbapp;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
public static final String REST_API = OpenAPI30Configuration.API_PREFIX;
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController(SecurityConfiguration.SPA_URL_MASK).setViewName("forward:/");
registry.addViewController("/notFound").setViewName("forward:/");
}
@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
return container -> container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound"));
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");

View File

@@ -0,0 +1,11 @@
package ru.ulstu.is.sbapp.jwt;
public class JwtException extends RuntimeException{
public JwtException(Throwable throwable) {
super(throwable);
}
public JwtException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,73 @@
package ru.ulstu.is.sbapp.jwt;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.GenericFilterBean;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
public class JwtFilter extends GenericFilterBean{
private static final String AUTHORIZATION = "Authorization";
public static final String TOKEN_BEGIN_STR = "Bearer ";
private final CustomerService customerService;
public JwtFilter(CustomerService customerService) {
this.customerService = customerService;
}
private String getTokenFromRequest(HttpServletRequest request) {
String bearer = request.getHeader(AUTHORIZATION);
if (StringUtils.hasText(bearer) && bearer.startsWith(TOKEN_BEGIN_STR)) {
return bearer.substring(TOKEN_BEGIN_STR.length());
}
return null;
}
private void raiseException(ServletResponse response, int status, String message) throws IOException {
if (response instanceof final HttpServletResponse httpResponse) {
httpResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
httpResponse.setStatus(status);
final byte[] body = new ObjectMapper().writeValueAsBytes(message);
response.getOutputStream().write(body);
}
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (request instanceof final HttpServletRequest httpRequest) {
final String token = getTokenFromRequest(httpRequest);
if (StringUtils.hasText(token)) {
try {
final UserDetails user = customerService.loadUserByToken(token);
final UsernamePasswordAuthenticationToken auth =
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
} catch (JwtException e) {
raiseException(response, HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
return;
} catch (Exception e) {
e.printStackTrace();
raiseException(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
String.format("Internal error: %s", e.getMessage()));
return;
}
}
}
chain.doFilter(request, response);
}
}

View File

@@ -0,0 +1,27 @@
package ru.ulstu.is.sbapp.jwt;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "jwt", ignoreInvalidFields = true)
public class JwtProperties {
private String devToken = "";
private Boolean isDev = true;
public String getDevToken() {
return devToken;
}
public void setDevToken(String devToken) {
this.devToken = devToken;
}
public Boolean isDev() {
return isDev;
}
public void setDev(Boolean dev) {
isDev = dev;
}
}

View File

@@ -0,0 +1,107 @@
package ru.ulstu.is.sbapp.jwt;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.Optional;
import java.util.UUID;
@Component
public class JwtProvider {
private final static Logger LOG = LoggerFactory.getLogger(JwtProvider.class);
private final static byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
private final static String ISSUER = "auth0";
private final Algorithm algorithm;
private final JWTVerifier verifier;
public JwtProvider(JwtProperties jwtProperties) {
if (!jwtProperties.isDev()) {
LOG.info("Generate new JWT key for prod");
try {
final MessageDigest salt = MessageDigest.getInstance("SHA-256");
salt.update(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
LOG.info("Use generated JWT key for prod \n{}", bytesToHex(salt.digest()));
algorithm = Algorithm.HMAC256(bytesToHex(salt.digest()));
} catch (NoSuchAlgorithmException e) {
throw new JwtException(e);
}
} else {
LOG.info("Use default JWT key for dev \n{}", jwtProperties.getDevToken());
algorithm = Algorithm.HMAC256(jwtProperties.getDevToken());
}
verifier = JWT.require(algorithm)
.withIssuer(ISSUER)
.build();
}
private static String bytesToHex(byte[] bytes) {
byte[] hexChars = new byte[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars, StandardCharsets.UTF_8);
}
public String generateToken(String login) {
final Date issueDate = Date.from(LocalDate.now()
.atStartOfDay(ZoneId.systemDefault())
.toInstant());
final Date expireDate = Date.from(LocalDate.now()
.plusDays(15)
.atStartOfDay(ZoneId.systemDefault())
.toInstant());
return JWT.create()
.withIssuer(ISSUER)
.withIssuedAt(issueDate)
.withExpiresAt(expireDate)
.withSubject(login)
.sign(algorithm);
}
private DecodedJWT validateToken(String token) {
try {
return verifier.verify(token);
} catch (JWTVerificationException e) {
throw new JwtException(String.format("Token verification error: %s", e.getMessage()));
}
}
public boolean isTokenValid(String token) {
if (!StringUtils.hasText(token)) {
return false;
}
try {
validateToken(token);
return true;
} catch (JwtException e) {
LOG.error(e.getMessage());
return false;
}
}
public Optional<String> getLoginFromToken(String token) {
try {
return Optional.ofNullable(validateToken(token).getSubject());
} catch (JwtException e) {
LOG.error(e.getMessage());
return Optional.empty();
}
}
}

View File

@@ -5,7 +5,7 @@ spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.ddl-auto=create-drop
spring.h2.console.enabled=true
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false

View File

@@ -1,16 +1,15 @@
package ru.ulstu.is.sbapp;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ulstu.is.sbapp.Models.Customer;
import ru.ulstu.is.sbapp.Services.CustomerService;
import ru.ulstu.is.sbapp.Customer.Exception.CustomerNotFoundException;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import javax.persistence.EntityNotFoundException;
import java.util.List;
@SpringBootTest
@@ -25,7 +24,7 @@ public class JpaCustomerTests
void testCustomerCreate()
{
customerService.deleteAllCustomers();
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
Assertions.assertNotNull(customer.getId());
}
@@ -34,7 +33,7 @@ public class JpaCustomerTests
void testCustomerRead()
{
customerService.deleteAllCustomers();
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Customer findCustomer = customerService.findCustomer(customer.getId());
log.info(findCustomer.toString());
@@ -45,15 +44,15 @@ public class JpaCustomerTests
void testCustomerReadNotFound()
{
customerService.deleteAllCustomers();
Assertions.assertThrows(EntityNotFoundException.class, () -> customerService.findCustomer(-1L));
Assertions.assertThrows(CustomerNotFoundException.class, () -> customerService.findCustomer(-1L));
}
@Test
void testCustomerReadAll()
{
customerService.deleteAllCustomers();
customerService.addCustomer("Nikita Lisov");
customerService.addCustomer("Evelina Aust Sergeevna");
customerService.addCustomer("Nikita Lisov","1234");
customerService.addCustomer("Evelina Aust Sergeevna","12345");
final List<Customer> customers = customerService.findAllCustomers();
log.info(customers.toString());
Assertions.assertEquals(customers.size(), 2);
@@ -72,7 +71,7 @@ public class JpaCustomerTests
void testCustomerChanges()
{
customerService.deleteAllCustomers();
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Customer changedCustomer = customerService.updateCustomer(customer.getId(),"Evelina Potter");
log.info(changedCustomer.toString());
@@ -84,10 +83,10 @@ public class JpaCustomerTests
{
customerService.deleteAllCustomers();
final Customer customer1 = customerService.addCustomer("Nikita Lisov");
final Customer customer2 = customerService.addCustomer("Evelina Potter");
final Customer customer1 = customerService.addCustomer("Nikita Lisov","1234");
final Customer customer2 = customerService.addCustomer("Evelina Potter","12345");
customerService.deleteCustomer(customer1.getId());
Assertions.assertThrows(EntityNotFoundException.class, () -> customerService.findCustomer(customer1.getId()));
Assertions.assertThrows(CustomerNotFoundException.class, () -> customerService.findCustomer(customer1.getId()));
}
}

View File

@@ -6,11 +6,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ulstu.is.sbapp.Models.Customer;
import ru.ulstu.is.sbapp.Models.Genre;
import ru.ulstu.is.sbapp.Services.GenreService;
import ru.ulstu.is.sbapp.Genre.Exception.GenreNotFoundException;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
import javax.persistence.EntityNotFoundException;
import java.util.List;
@SpringBootTest
@@ -45,7 +44,7 @@ public class JpaGenreTests
void testCustomerReadNotFound()
{
genreService.deleteAllGenres();
Assertions.assertThrows(EntityNotFoundException.class, () -> genreService.findGenre(-1L));
Assertions.assertThrows(GenreNotFoundException.class, () -> genreService.findGenre(-1L));
}
@Test
@@ -87,7 +86,7 @@ public class JpaGenreTests
final Genre genre1 = genreService.addGenre("Nikita Lisov");
final Genre genre2 = genreService.addGenre("Evelina Potter");
genreService.deleteGenre(genre1.getId());
Assertions.assertThrows(EntityNotFoundException.class, () -> genreService.findGenre(genre1.getId()));
Assertions.assertThrows(GenreNotFoundException.class, () -> genreService.findGenre(genre1.getId()));
}
}

View File

@@ -6,14 +6,14 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import ru.ulstu.is.sbapp.Services.MovieService;
import ru.ulstu.is.sbapp.Models.Movie;
import ru.ulstu.is.sbapp.Models.Customer;
import ru.ulstu.is.sbapp.Services.CustomerService;
import ru.ulstu.is.sbapp.Models.Genre;
import ru.ulstu.is.sbapp.Services.GenreService;
import ru.ulstu.is.sbapp.Movie.Exception.MovieNotFoundException;
import ru.ulstu.is.sbapp.Movie.Service.MovieService;
import ru.ulstu.is.sbapp.Movie.Model.Movie;
import ru.ulstu.is.sbapp.Customer.Model.Customer;
import ru.ulstu.is.sbapp.Customer.Service.CustomerService;
import ru.ulstu.is.sbapp.Genre.Model.Genre;
import ru.ulstu.is.sbapp.Genre.Service.GenreService;
import javax.persistence.EntityNotFoundException;
import java.util.ArrayList;
import java.util.List;
@@ -39,10 +39,10 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer);
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer.getId());
log.info(movie.toString());
Assertions.assertNotNull(movie.getId());
@@ -59,10 +59,10 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer);
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer.getId());
log.info(movie.toString());
@@ -82,9 +82,9 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer);
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer.getId());
log.info(movie.toString());
log.info(customer.getMovies().toString());
@@ -104,10 +104,10 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre, customer);
final Movie movie = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer.getId());
log.info(movie.toString());
final List<Movie> movies = movieService.findAllMovies();
@@ -126,16 +126,16 @@ public class JpaMovieTests
final Genre genre = genreService.addGenre("Fantasy");
log.info(genre.toString());
final Customer customer1 = customerService.addCustomer("Nikita Lisov");
final Customer customer1 = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer1.toString());
final Customer customer2 = customerService.addCustomer("Evelina Potter");
final Customer customer2 = customerService.addCustomer("Evelina Potter","5678");
log.info(customer2.toString());
final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre, customer1);
final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre.getId(), customer1.getId());
log.info(movie1.toString());
final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre, customer2);
final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre.getId(), customer2.getId());
log.info(movie2.toString());
final List<Movie> movies = movieService.findAllMovies();
@@ -151,7 +151,7 @@ public class JpaMovieTests
customerService.deleteAllCustomers();
genreService.deleteAllGenres();
Assertions.assertThrows(EntityNotFoundException.class, () -> movieService.findMovie(-1L));
Assertions.assertThrows(MovieNotFoundException.class, () -> movieService.findMovie(-1L));
}
@Test
@@ -180,23 +180,23 @@ public class JpaMovieTests
final Genre genre2 = genreService.addGenre("Sci-Fi");
log.info(genre2.toString());
final Customer customer = customerService.addCustomer("Nikita Lisov");
final Customer customer = customerService.addCustomer("Nikita Lisov","1234");
log.info(customer.toString());
final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre1, customer);
final Movie movie1 = movieService.addMovie("Arcane",36,4.5, genre1.getId(), customer.getId());
log.info(movie1.toString());
final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre1, customer);
final Movie movie2 = movieService.addMovie("Harry Potter",128,10.0, genre1.getId(), customer.getId());
log.info(movie2.toString());
final Movie movie3 = movieService.addMovie("Interstellar",2,9.5, genre2, customer);
final Movie movie3 = movieService.addMovie("Interstellar",2,9.5, genre2.getId(), customer.getId());
log.info(movie3.toString());
List<Movie> movies = new ArrayList<>(){};
movies.add(movie1);
movies.add(movie2);
List<Movie> expectedMovies = movieService.findAllSpecificMovies(genre1);
List<Movie> expectedMovies = movieService.findAllSpecificMovies(genre1.getName());
log.info(expectedMovies.toString());
Assertions.assertArrayEquals(movies.toArray(),expectedMovies.toArray());

View File

@@ -1,6 +1,11 @@
spring.datasource.url=jdbc:h2:mem:testdb
spring.main.banner-mode=off
#server.port=8080
spring.datasource.url=jdbc:h2:file:./data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false