Error Handling in Java Capture and raise Event in Alibaba Cloud

87 views Asked by At

I am new to Java and in the learning curve. I have a in Alicloud integration where I am creating a java Function Compute.

I need to connect to Key Management Service (KMS) to get the secret. In case the KMS is not available or not able to connect by function then I need to create a Event message in a topic in MNS. I wanted to know how do I handle this error ?

Code snippet is below.

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());
           
       }
       }
   
    }

Basically I want to capture the error which comes at runtime and do some action based upon that.

For Example:

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

Error descriptions for Alibaba Cloud KMS is detailed here

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

Can someone please help me in catching the error and raise publish a message in MNS?

Thanks, Amdone

1

There are 1 answers

1
wanghq On

I assume you will async invoke the function instead of sync invoke it. If so, there is a much simpler solution by which you don't need to write code to notify MNS.

Alibaba Cloud Function Compute supports Destination feature

Here is the process:

  1. You configure the async invoke config for the function - when the function returns abnormally, notifies a MNS topic.
  2. In the function, you call KMS. If succeeds, you do your business logic; Otherwise just throw exception.

That's it!