0

我是 Java 新手并且处于学习曲线中。我有一个阿里云集成,我正在创建一个 java 函数计算。

我需要连接到密钥管理服务 (KMS) 以获取密钥。如果 KMS 不可用或无法通过功能连接,那么我需要在 MNS 的主题中创建事件消息。我想知道如何处理这个错误?

代码片段如下。

public class SFTP14 implements StreamRequestHandler, FunctionInitializer {

    public void initialize(Context context) throws IOException {
    }


    public void handleRequest( InputStream inputStream
                             , OutputStream outputStream
                             , Context context) throws IOException 
    {
       
       // Get values from Environment varaible of function
       String bucketname = System.getenv("BUCKET_NAME");
       String endpoint = System.getenv("ENDPOINT");
       String kmssecret = System.getenv("KMSSECRET");
       String MNSEndpoint="http://mns.cn-shanghai.aliyuncs.com/";
      
       outputStream.write(new String("Bucket Name:"+bucketname +" \n").getBytes());
       outputStream.write(new String("End Point Name:"+endpoint +" \n").getBytes());

      // Get credential from Funcion compute service 
      Credentials creds = context.getExecutionCredentials();

      String AccessID= creds.getAccessKeyId();
      String AccessKey= creds.getAccessKeySecret();
      String SecurityToken =creds.getSecurityToken();

           //outputStream.write(new String("Secret AccessID:"+AccessID +" \n").getBytes());
           //outputStream.write(new String("Secret AccessKey:"+AccessKey +" \n").getBytes());

       //DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKeyId, accessKeySecret);
       DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", AccessID, AccessKey,SecurityToken);

       IAcsClient client = new DefaultAcsClient(profile);

      // Get secret data from KMS
        GetSecretValueRequest request = new GetSecretValueRequest();
        request.setSecretName(kmssecret);
      
   
    CloudAccount account = new CloudAccount(AccessID,AccessKey,ServiceSettings.getMNSAccountEndpoint(),SecurityToken);
    
    //DefaultMNSClient MNSclient = new DefaultMNSClient(creds.getAccessKeyId(), creds.getAccessKeySecret(),MNSEndpoint) ;

    CloudTopic topic = MNSclient.getTopicRef("myTopic");
      
    try
       {
           GetSecretValueResponse response = client.getAcsResponse(request);
            
           **if (response== null)
           {
              
               throw new Exception("Cant connect to KMS"); 
           }**
           JSONObject obj= new JSONObject(response);
           
           String SecretData = obj.getString("secretData");
           
           JSONObject SecretData1= new JSONObject(SecretData);
           
           String user = SecretData1.getString("username");
           String password = SecretData1.getString("password");
           String host = SecretData1.getString("host");
           String port1 = SecretData1.getString("port");
           int port=Integer.parseInt(port1);  
           String remotePath = SecretData1.getString("remotepath");

            // Print values got from KMS Secret
           outputStream.write(new String("Secret UserName:"+user +" \n").getBytes());
           outputStream.write(new String("Secret Password:"+password +" \n").getBytes());
           outputStream.write(new String("Secret Host:"+host +" \n").getBytes());
           outputStream.write(new String("Secret Port:"+port1 +" \n").getBytes());
           outputStream.write(new String("Secret remotePath:"+remotePath +" \n\n").getBytes());
      
           //TopicMessage msg1 = new TopicMessage(); // You can specify whether to perform Base64 encoding on topic messages.
           TopicMessage  msg = new RawTopicMessage();  
           //TopicMessage  msg1 = new RawTopicMessage(); 

           outputStream.write(new String("hello world to AliCloud\n").getBytes());
          // Create an OSSClient instance.
          outputStream.write(new String("Start to create OSS client\n").getBytes());
         // OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
         OSS ossClient = new OSSClientBuilder().build(endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret() ,creds.getSecurityToken());

          outputStream.write(new String("OSS client created.\n").getBytes());

          JSch jsch = new JSch();
          outputStream.write(new String("Jsch instanciated\n").getBytes());
          
          Session session = jsch.getSession(user, host, port);
          session.setPassword(password);
          // rational
          session.setConfig("StrictHostKeyChecking", "no");

          outputStream.write(new String("Jsch session created, Establishing Connection...\n").getBytes());
          session.connect();
          outputStream.write(new String("...Connection established\n").getBytes());
          outputStream.write(new String("establish sftp channel...\n").getBytes());
          ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
          sftpChannel.connect();
          outputStream.write(new String("...sftp channel established\n").getBytes());

          sftpChannel.cd(remotePath);
            outputStream.write(new String("...changed directory\n").getBytes());

            Vector lsVector = sftpChannel.ls("*");
          outputStream.write(new String("ls vector created\n").getBytes());

          Enumeration en = lsVector.elements();
          outputStream.write(new String("ls elements are:\n").getBytes());
          String filename;
          ChannelSftp.LsEntry LsEntry;

          if(lsVector.isEmpty()==true) 
          {
              outputStream.write(new String("Publish Message \n").getBytes());

              //msg.setMessageBody("hello world!") ;
              msg.setMessageBody(("hello bytes with tag! ").getBytes());

              msg = topic.publishMessage(msg);  
           throw new Exception("No File Found"); 
          }
          else
          {
          while(en.hasMoreElements()) 
          {
         LsEntry = (ChannelSftp.LsEntry)en.nextElement();
          filename = LsEntry.getFilename();
           // else {
           outputStream.write(new String(filename+" \n").getBytes());
           
           InputStream fileIS = sftpChannel.get(filename);
           // filename with extension ?
           ossClient.putObject(bucketname, filename, fileIS);
           
           // remove remote file from FTP server
           sftpChannel.rm(filename);
          // }
         }
          }      
          // Shut down the OSSClient instance.
          ossClient.shutdown();

          sftpChannel.disconnect();
          outputStream.write(new String("sftp channel disconnected\n").getBytes());
          session.disconnect();
            outputStream.write(new String("disconnected from session\n").getBytes());
       }
       catch(Exception e)
       {
           outputStream.write(new String("Error Message:"+e.getMessage() +" \n\n").getBytes());
           
       }
       }
   
    }

基本上我想捕获运行时出现的错误并基于此执行一些操作。

例如:

if exception=Forbidden.NoPermission
then 
Publish a message in topic with the error message occurs.

阿里云 KMS 的错误描述在此处详细说明

https://error-center.alibabacloud.com/status/product/Kms?spm=a2c69.11428812.home.32.1f39bb9amMIo4u

有人可以帮我发现错误并在 MNS 中发布消息吗?

谢谢, 安多

4

1 回答 1

0

我假设您将异步调用该函数而不是同步调用它。如果是这样,有一个更简单的解决方案,您无需编写代码来通知 MNS。

阿里云函数计算支持Destination特性

这是过程:

  1. 您为函数配置异步调用配置 - 当函数异常返回时,通知 MNS 主题。
  2. 在函数中,您调用 KMS。如果成功,则执行您的业务逻辑;否则只是抛出异常。

而已!

于 2020-12-04T01:15:45.393 回答