25 Haziran 2020 Perşembe

How to check the size of a table of a MySQL database?

This sql code is used to determine the size of a table of a MySQL database:
SELECT
  TABLE_NAME AS `Table`,
  ROUND(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024),2) AS `Size (MB)`
FROM
  information_schema.TABLES
WHERE
    TABLE_SCHEMA = "schemaName"
  AND
    TABLE_NAME = "tableName"
ORDER BY
  (DATA_LENGTH + INDEX_LENGTH)
DESC;
schemaName and tableName should be changed with real name of schema and table in your case.

The result will be seen like:
+-------------+-------------+
| Table          | Size (MB) |
+-------------+-------------+
| tableName |       267      |
+-------------+-------------+
1 row in set (0.00 sec)

18 Temmuz 2019 Perşembe

How to deploy and use a MySQL Docker container

# Pull latest docker mysql image from docker repo
docker pull mysql/mysql-server:latest
# Create a docker container and run it
docker run -d --name CONTAINER --restart=always -p 3306:3306 mysql/mysql-server:latest
# Check the automatically generated password of root user
docker logs CONTAINER 2>&1 | grep GENERATED
# Connect mysql server with root account and enter the password (that will appear after previous command above!)
docker exec -it CONTAINER mysql -u root -p
# Give a new password to root
ALTER USER 'root'@'localhost' IDENTIFIED BY '<db_root_password>';
# Create user a database and a user. Give all privileges to this user for all tables in test DB.
CREATE DATABASE test_db;
CREATE USER 'test-user'@'localhost' IDENTIFIED BY '<db_test_password>';
GRANT ALL PRIVILEGES ON test_db.* TO 'test-user'@'localhost';
FLUSH PRIVILEGES;
exit;
# Restore DB with sql file that is created in backup by MySQL Workbench
cat backup.sql | docker exec -I CONTAINER /usr/bin/mysql -u test-user -p<db_test_password> test_db
# If necessary, to backup DB:
cat backup.sql | docker exec -I CONTAINER /usr/bin/mysql -u test-user —password=<db_test_password> test_db

11 Ocak 2019 Cuma

com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input

Problem: 
Server - provide REST services
Client - consume them via Spring restTemplate. jackson-datatype-jsr310 library is used to parse JSON response.

In addition to the HTTP status, the server returns an HTTP body with JSON that describes an error in detail. I have custom error handler to restTemplate to treat some error coded as non errors - it helps parse HTTP body very well.

However, in some cases, client(my app) gets Http 401 response with empty body:
if (HttpStatus.UNAUTHORIZED == httpStatus) {
        final ClientErrorInfo error;
        try {
            error = mapper.readValue(exception.getResponseBodyAsString(), ClientErrorInfo.class);

            final String errorCode = error.getErrorCode();

            logBackendError(httpMethod, url, headers,
                httpStatus, errorCode, error.getErrorMessage(), error.getErrorCause());

            errorResponse = errorResponseConverter.prepareErrorResponse(errorCode, response);
        } catch (IOException ioException) {
            errorResponse = generateUnexpectedJsonFormatError(ioException);
        }
    }
I mean, exception.getResponseBodyAsString() returns null. Because of this, mapper.readValue(exception.getResponseBodyAsString(), ClientErrorInfo.class) cannot parse null value to ClientErrorInfo.class. Then, JsonMappingException is thrown:
com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input
 at [Source: ; line: 1, column: 0]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
    at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:3854)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3799)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2858)
    at com.commencis.butterfly.core.RestResponseEntityExceptionHandler.handleBackendClientException(RestResponseEntityExceptionHandler.java:145)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
    at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:384)
    at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:59)
    at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:136)
    at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:74)
    at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1222)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1034)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:984)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:167)
    at org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
By using Charles, I intervened between client and server and checked the response before client(my app) received. Response was something like:
HTTP/1.1 401 Unauthorized
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=C157382C48E***9972A77DADC; Path=/crane-ticketing; Secure; HttpOnly
Set-Cookie: rememberMe=deleteMe; Path=/crane-ticketing; Max-Age=0; Expires=Tue, 04-Dec-2018 13:38:02 GMT
Content-Type: application/json;charset=UTF-8
Content-Length: 100
Date: Wed, 05 Dec 2018 13:38:01 GMT
Connection: Keep-alive

{"errorCode":"ERR_C13","errorMessage":"Authorization failed","errorCause":"RETRIEVABLE_PNR_SR_CODE"}
Solution:
After I made some debugging, I realized that the cause of the problem was the code in SimpleClientHttpResponse that is a default response class of Resttemplate. Also, I found that there were some issues about this problem in Spring JIRA:

"It is very difficult (impossible) to handle a 401 response in the RestTemplate with default settings. In fact it is possible, but you have to supply an error handler and a request factory. The error handler was obvious, but the problem is that the default request factory uses java.net which can throw HttpRetryException when you try to look at the status code of the response (despite it being obviously available). The solution is to use HttpComponentsClientHttpRequestFactory."

When I added the dependency written below in my POM file, my application started to handle the body of 401 response.
<dependency>
   <groupId>org.apache.httpcomponents</groupId>
   <artifactId>httpclient</artifactId>
</dependency>
References:
  1. https://stackoverflow.com/questions/16748969/java-net-httpretryexception-cannot-retry-due-to-server-authentication-in-strea/53695761#53695761
  2. https://stackoverflow.com/questions/47429978/resttemplate-response-getbody-throws-exception-on-4-and-5-errors-for-put-and
  3. https://stackoverflow.com/questions/54022183/com-fasterxml-jackson-databind-jsonmappingexception-no-content-to-map-due-to-en/54142909#54142909
  4. https://jira.spring.io/browse/SPR-9367