This is an automated email from the ASF dual-hosted git repository.

panjuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 3f242ff  Refactor PostgreSQLAuthenticationEngine (#10163)
3f242ff is described below

commit 3f242ff561267a28c7fb6fe94516cb028c7817c3
Author: 吴伟杰 <[email protected]>
AuthorDate: Fri Apr 23 22:39:13 2021 +0800

    Refactor PostgreSQLAuthenticationEngine (#10163)
    
    * Throw exception rather than write response in many places
    
    * Remove unused exception handling
---
 .../constant/PostgreSQLMessageSeverityLevel.java   | 52 +++++++++++++++++++++
 .../netty/FrontendChannelInboundHandler.java       |  3 +-
 .../PostgreSQLAuthenticationEngine.java            | 53 ++++++----------------
 .../PostgreSQLAuthenticationHandler.java           |  3 +-
 ...InvalidAuthorizationSpecificationException.java | 34 ++++++++++++++
 .../PostgreSQLAuthenticationException.java         | 37 +++++++++++++++
 .../PostgreSQLProtocolViolationException.java      | 36 +++++++++++++++
 .../postgresql/err/PostgreSQLErrPacketFactory.java | 31 +++++++++----
 .../PostgreSQLAuthenticationEngineTest.java        |  9 ++--
 9 files changed, 204 insertions(+), 54 deletions(-)

diff --git 
a/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/constant/PostgreSQLMessageSeverityLevel.java
 
b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/constant/PostgreSQLMessageSeverityLevel.java
new file mode 100644
index 0000000..311d2c2
--- /dev/null
+++ 
b/shardingsphere-db-protocol/shardingsphere-db-protocol-postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/constant/PostgreSQLMessageSeverityLevel.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.db.protocol.postgresql.constant;
+
+/**
+ * PostgreSQL message severity level.
+ *
+ * @see <a 
href="https://www.postgresql.org/docs/12/runtime-config-logging.html#RUNTIME-CONFIG-SEVERITY-LEVELS";>Table
 19.2. Message Severity Levels</a>
+ */
+public enum PostgreSQLMessageSeverityLevel {
+    
+    DEBUG0,
+    
+    DEBUG1,
+    
+    DEBUG2,
+    
+    DEBUG3,
+    
+    DEBUG4,
+    
+    DEBUG5,
+    
+    INFO,
+    
+    NOTICE,
+    
+    WARNING,
+    
+    ERROR,
+    
+    LOG,
+    
+    FATAL,
+    
+    PANIC
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-core/src/main/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandler.java
 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-core/src/main/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandler.java
index d823b97..c0243a9 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-core/src/main/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandler.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-core/src/main/java/org/apache/shardingsphere/proxy/frontend/netty/FrontendChannelInboundHandler.java
@@ -78,7 +78,8 @@ public final class FrontendChannelInboundHandler extends 
ChannelInboundHandlerAd
         } catch (final Exception ex) {
             // CHECKSTYLE:ON
             log.error("Exception occur: ", ex);
-            
context.write(databaseProtocolFrontendEngine.getCommandExecuteEngine().getErrorPacket(ex));
+            
context.writeAndFlush(databaseProtocolFrontendEngine.getCommandExecuteEngine().getErrorPacket(ex));
+            context.close();
         }
         return false;
     }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
index caaea6d..bcb9912 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
@@ -22,7 +22,6 @@ import io.netty.channel.ChannelHandlerContext;
 import org.apache.shardingsphere.db.protocol.payload.PacketPayload;
 import 
org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLErrorCode;
 import 
org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.binary.BinaryStatementRegistry;
-import 
org.apache.shardingsphere.db.protocol.postgresql.packet.generic.PostgreSQLErrorResponsePacket;
 import 
org.apache.shardingsphere.db.protocol.postgresql.packet.generic.PostgreSQLReadyForQueryPacket;
 import 
org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.PostgreSQLAuthenticationMD5PasswordPacket;
 import 
org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.PostgreSQLAuthenticationOKPacket;
@@ -33,14 +32,13 @@ import 
org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.Postgre
 import 
org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.PostgreSQLSSLNegativePacket;
 import 
org.apache.shardingsphere.db.protocol.postgresql.packet.identifier.PostgreSQLMessagePacketType;
 import 
org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
-import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import 
org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationEngine;
 import 
org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResult;
 import 
org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResultBuilder;
 import 
org.apache.shardingsphere.proxy.frontend.connection.ConnectionIdGenerator;
-import 
org.apache.shardingsphere.proxy.frontend.postgresql.err.PostgreSQLErrPacketFactory;
-import org.postgresql.util.PSQLException;
-import org.postgresql.util.ServerErrorMessage;
+import 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.InvalidAuthorizationSpecificationException;
+import 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLAuthenticationException;
+import 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLProtocolViolationException;
 
 /**
  * Authentication engine for PostgreSQL.
@@ -77,55 +75,32 @@ public final class PostgreSQLAuthenticationEngine 
implements AuthenticationEngin
     private AuthenticationResult processStartupMessage(final 
ChannelHandlerContext context, final PostgreSQLPacketPayload payload) {
         startupMessageReceived = true;
         PostgreSQLComStartupPacket comStartupPacket = new 
PostgreSQLComStartupPacket(payload);
-        String database = comStartupPacket.getDatabase();
-        if (!Strings.isNullOrEmpty(database) && 
!ProxyContext.getInstance().schemaExists(database)) {
-            
context.writeAndFlush(createErrorPacket(PostgreSQLErrorCode.INVALID_CATALOG_NAME,
 String.format("database \"%s\" does not exist", database)));
-            context.close();
-            return AuthenticationResultBuilder.continued();
-        }
         String user = comStartupPacket.getUser();
         if (Strings.isNullOrEmpty(user)) {
-            
context.writeAndFlush(createErrorPacket(PostgreSQLErrorCode.SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION,
 "user not set in StartupMessage"));
-            context.close();
-            return AuthenticationResultBuilder.continued();
+            throw new InvalidAuthorizationSpecificationException("no 
PostgreSQL user name specified in startup packet");
         }
         md5Salt = 
PostgreSQLRandomGenerator.getInstance().generateRandomBytes(4);
         context.writeAndFlush(new 
PostgreSQLAuthenticationMD5PasswordPacket(md5Salt));
-        currentAuthResult = AuthenticationResultBuilder.continued(user, "", 
database);
+        currentAuthResult = AuthenticationResultBuilder.continued(user, "", 
comStartupPacket.getDatabase());
         return currentAuthResult;
     }
     
     private AuthenticationResult processPasswordMessage(final 
ChannelHandlerContext context, final PostgreSQLPacketPayload payload) {
         char messageType = (char) payload.readInt1();
         if (PostgreSQLMessagePacketType.PASSWORD_MESSAGE.getValue() != 
messageType) {
-            PostgreSQLErrorResponsePacket responsePacket = createErrorPacket(
-                    
PostgreSQLErrorCode.SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION, 
String.format("PasswordMessage is expected, message type 'p', but not '%s'", 
messageType));
-            context.writeAndFlush(responsePacket);
-            context.close();
-            currentAuthResult = AuthenticationResultBuilder.continued();
-            return currentAuthResult;
+            throw new PostgreSQLProtocolViolationException("password", 
Character.toString(messageType));
         }
         PostgreSQLPasswordMessagePacket passwordMessagePacket = new 
PostgreSQLPasswordMessagePacket(payload);
         PostgreSQLLoginResult loginResult = 
PostgreSQLAuthenticationHandler.loginWithMd5Password(currentAuthResult.getUsername(),
 currentAuthResult.getDatabase(), md5Salt, passwordMessagePacket);
         if (PostgreSQLErrorCode.SUCCESSFUL_COMPLETION != 
loginResult.getErrorCode()) {
-            PostgreSQLErrorResponsePacket responsePacket = 
createErrorPacket(loginResult.getErrorCode(), loginResult.getErrorMessage());
-            context.writeAndFlush(responsePacket);
-            context.close();
-            return AuthenticationResultBuilder.continued();
-        } else {
-            // TODO implement PostgreSQLServerInfo like MySQLServerInfo
-            context.write(new PostgreSQLAuthenticationOKPacket(true));
-            context.write(new 
PostgreSQLParameterStatusPacket("server_version", "12.3"));
-            context.write(new 
PostgreSQLParameterStatusPacket("client_encoding", "UTF8"));
-            context.write(new 
PostgreSQLParameterStatusPacket("server_encoding", "UTF8"));
-            context.writeAndFlush(new PostgreSQLReadyForQueryPacket());
-            return 
AuthenticationResultBuilder.finished(currentAuthResult.getUsername(), "", 
currentAuthResult.getDatabase());
+            throw new 
PostgreSQLAuthenticationException(loginResult.getErrorCode(), 
loginResult.getErrorMessage());
         }
-    }
-    
-    private PostgreSQLErrorResponsePacket createErrorPacket(final 
PostgreSQLErrorCode errorCode, final String errorMessage) {
-        String message = Strings.isNullOrEmpty(errorMessage) ? 
errorCode.getConditionName() : errorMessage;
-        PostgreSQLErrorResponsePacket packet = 
PostgreSQLErrorResponsePacket.newBuilder("FATAL", errorCode.getErrorCode(), 
message).build();
-        return PostgreSQLErrPacketFactory.newInstance(new PSQLException(new 
ServerErrorMessage(packet.toServerErrorMessage())));
+        // TODO implement PostgreSQLServerInfo like MySQLServerInfo
+        context.write(new PostgreSQLAuthenticationOKPacket(true));
+        context.write(new PostgreSQLParameterStatusPacket("server_version", 
"12.3"));
+        context.write(new PostgreSQLParameterStatusPacket("client_encoding", 
"UTF8"));
+        context.write(new PostgreSQLParameterStatusPacket("server_encoding", 
"UTF8"));
+        context.writeAndFlush(new PostgreSQLReadyForQueryPacket());
+        return 
AuthenticationResultBuilder.finished(currentAuthResult.getUsername(), "", 
currentAuthResult.getDatabase());
     }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
index f73d7e8..bb3be67 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.proxy.frontend.postgresql.authentication;
 
+import com.google.common.base.Strings;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.commons.codec.binary.Hex;
@@ -56,7 +57,7 @@ public final class PostgreSQLAuthenticationHandler {
         }
         String md5Digest = passwordMessagePacket.getMd5Digest();
         String expectedMd5Digest = md5Encode(username, 
user.get().getPassword(), md5Salt);
-        if (!expectedMd5Digest.equals(md5Digest)) {
+        if (!expectedMd5Digest.equals(md5Digest) || 
!Strings.isNullOrEmpty(databaseName) && 
!ProxyContext.getInstance().schemaExists(databaseName)) {
             return new 
PostgreSQLLoginResult(PostgreSQLErrorCode.INVALID_PASSWORD, 
String.format("password authentication failed for user \"%s\"", username));
         }
         return null == databaseName || SQLCheckEngine.check(databaseName, 
getRules(databaseName), user.get().getGrantee())
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/InvalidAuthorizationSpecificationException.java
 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/InvalidAuthorizationSpecificationException.java
new file mode 100644
index 0000000..33343e7
--- /dev/null
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/InvalidAuthorizationSpecificationException.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.proxy.frontend.exception.FrontendException;
+
+/**
+ * Invalid authorization specification exception.
+ */
+@Getter
+@RequiredArgsConstructor
+public final class InvalidAuthorizationSpecificationException extends 
FrontendException {
+    
+    private static final long serialVersionUID = -7169979989631579431L;
+    
+    private final String message;
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLAuthenticationException.java
 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLAuthenticationException.java
new file mode 100644
index 0000000..e0024e6
--- /dev/null
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLAuthenticationException.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLErrorCode;
+import org.apache.shardingsphere.proxy.frontend.exception.FrontendException;
+
+/**
+ * PostgreSQL authentication exception.
+ */
+@Getter
+@RequiredArgsConstructor
+public final class PostgreSQLAuthenticationException extends FrontendException 
{
+    
+    private static final long serialVersionUID = 1331782847269278560L;
+    
+    private final PostgreSQLErrorCode errorCode;
+    
+    private final String message;
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLProtocolViolationException.java
 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLProtocolViolationException.java
new file mode 100644
index 0000000..87db44d
--- /dev/null
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/exception/PostgreSQLProtocolViolationException.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.proxy.frontend.exception.FrontendException;
+
+/**
+ * PostgreSQL protocol violation exception.
+ */
+@Getter
+@RequiredArgsConstructor
+public final class PostgreSQLProtocolViolationException extends 
FrontendException {
+    
+    private static final long serialVersionUID = 6784109729740919997L;
+    
+    private final String expectedMessageType;
+    
+    private final String actualMessageType;
+}
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/err/PostgreSQLErrPacketFactory.java
 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/err/PostgreSQLErrPacketFactory.java
index 2712273..e1a3392 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/err/PostgreSQLErrPacketFactory.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/err/PostgreSQLErrPacketFactory.java
@@ -21,7 +21,11 @@ import com.google.common.base.Strings;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import 
org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLErrorCode;
+import 
org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLMessageSeverityLevel;
 import 
org.apache.shardingsphere.db.protocol.postgresql.packet.generic.PostgreSQLErrorResponsePacket;
+import 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.InvalidAuthorizationSpecificationException;
+import 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLAuthenticationException;
+import 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLProtocolViolationException;
 import org.postgresql.util.PSQLException;
 import org.postgresql.util.ServerErrorMessage;
 
@@ -44,9 +48,23 @@ public final class PostgreSQLErrPacketFactory {
             return createErrorResponsePacket(((PSQLException) 
cause).getServerErrorMessage());
         }
         if (cause instanceof SQLException) {
-            return createErrorResponsePacket((SQLException) cause);
+            // TODO consider what severity to use
+            return 
PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.ERROR.name(),
 ((SQLException) cause).getSQLState(), cause.getMessage()).build();
         }
-        return createErrorResponsePacket(cause);
+        if (cause instanceof InvalidAuthorizationSpecificationException) {
+            return 
PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.FATAL.name(),
 PostgreSQLErrorCode.INVALID_AUTHORIZATION_SPECIFICATION.getErrorCode(), 
cause.getMessage())
+                    
.severityNonLocalized(PostgreSQLMessageSeverityLevel.FATAL.name()).build();
+        }
+        if (cause instanceof PostgreSQLProtocolViolationException) {
+            return 
PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.FATAL.name(),
 PostgreSQLErrorCode.PROTOCOL_VIOLATION.getErrorCode(),
+                    String.format("expected %s response, got message type %s", 
((PostgreSQLProtocolViolationException) cause).getExpectedMessageType(),
+                            ((PostgreSQLProtocolViolationException) 
cause).getActualMessageType())).severityNonLocalized(PostgreSQLMessageSeverityLevel.FATAL.name()).build();
+        }
+        if (cause instanceof PostgreSQLAuthenticationException) {
+            return 
PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.FATAL.name(),
 ((PostgreSQLAuthenticationException) cause).getErrorCode().getErrorCode(), 
cause.getMessage())
+                    .build();
+        }
+        return createErrorResponsePacketForUnknownException(cause);
     }
     
     private static PostgreSQLErrorResponsePacket 
createErrorResponsePacket(final ServerErrorMessage serverErrorMessage) {
@@ -57,14 +75,9 @@ public final class PostgreSQLErrPacketFactory {
                 
.constraintName(serverErrorMessage.getConstraint()).file(serverErrorMessage.getFile()).line(serverErrorMessage.getLine()).routine(serverErrorMessage.getRoutine()).build();
     }
     
-    private static PostgreSQLErrorResponsePacket 
createErrorResponsePacket(final SQLException cause) {
-        // TODO consider what severity to use
-        return PostgreSQLErrorResponsePacket.newBuilder("ERROR", 
cause.getSQLState(), cause.getMessage()).build();
-    }
-    
-    private static PostgreSQLErrorResponsePacket 
createErrorResponsePacket(final Exception cause) {
+    private static PostgreSQLErrorResponsePacket 
createErrorResponsePacketForUnknownException(final Exception cause) {
         // TODO add FIELD_TYPE_CODE for common error and consider what 
severity to use
         String message = Strings.isNullOrEmpty(cause.getLocalizedMessage()) ? 
cause.toString() : cause.getLocalizedMessage();
-        return PostgreSQLErrorResponsePacket.newBuilder("ERROR", 
PostgreSQLErrorCode.SYSTEM_ERROR.getErrorCode(), message).build();
+        return 
PostgreSQLErrorResponsePacket.newBuilder(PostgreSQLMessageSeverityLevel.ERROR.name(),
 PostgreSQLErrorCode.SYSTEM_ERROR.getErrorCode(), message).build();
     }
 }
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
index 85db4a5..71255d9 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
@@ -30,6 +30,8 @@ import 
org.apache.shardingsphere.infra.context.metadata.impl.StandardMetaDataCon
 import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import 
org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResult;
+import 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.InvalidAuthorizationSpecificationException;
+import 
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.exception.PostgreSQLAuthenticationException;
 import org.apache.shardingsphere.transaction.context.TransactionContexts;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -82,13 +84,12 @@ public final class PostgreSQLAuthenticationEngineTest {
         assertThat(actual.isFinished(), is(false));
     }
     
-    @Test
+    @Test(expected = InvalidAuthorizationSpecificationException.class)
     public void assertUserNotSet() {
         PostgreSQLPacketPayload payload = new 
PostgreSQLPacketPayload(createByteBuf(8, 512));
         payload.writeInt4(64);
         payload.writeInt4(196608);
-        AuthenticationResult actual = new 
PostgreSQLAuthenticationEngine().authenticate(mock(ChannelHandlerContext.class),
 payload);
-        assertThat(actual.isFinished(), is(false));
+        new 
PostgreSQLAuthenticationEngine().authenticate(mock(ChannelHandlerContext.class),
 payload);
     }
     
     @Test
@@ -96,7 +97,7 @@ public final class PostgreSQLAuthenticationEngineTest {
         assertLogin(password);
     }
     
-    @Test
+    @Test(expected = PostgreSQLAuthenticationException.class)
     public void assertLoginFailed() {
         assertLogin("wrong" + password);
     }

Reply via email to