By Du Wan
Alibaba Cloud Function Compute is a fully hosted and serverless running environment that takes away the need to manage infrastructure and enables businesses to focus on software development. You can deploy microservices on Alibaba Cloud with Function Compute; in this article, we will be doing this with the Cloud Customer Service product as an example.
Note: At the time of writing, Cloud Customer Service is only available for Mainland China Alibaba Cloud accounts.
Alibaba Cloud's Cloud Customer Service is a complete intelligent service system that can be easily integrated into websites, applications, public accounts, and other systems. Cloud Customer Service provides complete hotline and online service functions for users to easily access other systems such as CRM. It dynamically manages the centralized knowledge bases and knowledge documents used by customers and agents. Based on Alibaba Cloud's intelligent algorithms, chatbots can accurately understand your intention and answer any questions. In addition, it collects and analyzes the data in the customer service center in real time, helping enterprise decision-makers understand the most common issues and service bottlenecks from a global perspective.
As a function of Cloud Customer Service, Visitor Card associates the users of Cloud Customer Service with those in the CRM system to help the customer service personnel understand the customers' basic information for better support.
The Visitor Card Integration Guide provided by Cloud Customer Service is a web project implemented based on Spring MVC. For users who use Node.js, they can migrate from Java to Function Compute and provide function as a service for core business calls implemented with Node.js.
Users have tried to migrate Java by themselves but encountered the following technical challenges:
fccsplatform-common-crypto-1.0.0.20161108.jar is a package in the Maven warehouse in Alibaba Cloud's internal network. It is only available to external network customers through Cloud Customer Service. The following XML fragment is a common way in which Maven depends on local JAR packages. Because this is not a typical scenario, additional information is required to complete it.
<dependency>
<groupId>com.alipay.fc.csplatform</groupId>
<artifactId>fccsplatform-common-crypto</artifactId>
<version>1.0.0.20161108</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/fccsplatform-common-crypto-1.0.0.20161108.jar</systemPath>
</dependency>
<scope>system</scope>
indicates that the JAR package is searched from the system path rather than the warehouse. This command must be used with <systemPath/>
. <systemPath/>
indicates the actual path of a JAR package. This command is normally used with ${project.basedir}
(namely, it is relative to the project directory).
Spring MVC exposes a service as a Controller. For Function Compute, only a Handler API is required.
/**
* This is the interface for any none event based function handler
*/
public interface StreamRequestHandler {
/**
* The interface to handle a function compute invoke request
*
* @param input The function compute input data wrapped in a stream
* @param output The function compute output data wrapped in a stream
* @param context The function compute execution environment context object.
* @throws IOException IOException during I/O handling
*/
void handleRequest(InputStream input, OutputStream output, Context context) throws IOException;
}
Visitor Card services are simple, and only require an encryption API and a decoding API without calling any third-party services.
public class Encryptor implements StreamRequestHandler {
private CustomerInfo customerInfo = new CustomerInfo();
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
String cInfo = CharStreams.toString(new InputStreamReader(
input, Charset.defaultCharset()));
try {
output.write(customerInfo.encrypt(cInfo).getBytes(Charset.defaultCharset()));
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
}
public class Decryptor implements StreamRequestHandler {
private CustomerInfo customerInfo = new CustomerInfo();
@Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
String jsonString = CharStreams.toString(new InputStreamReader(
input, Charset.defaultCharset()));
JSONObject jsonObject = JSON.parseObject(jsonString);
try {
String cInfo = customerInfo.decrypt(jsonObject.getString("params"), jsonObject.getString("key"));
output.write(cInfo.getBytes(Charset.defaultCharset()));
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
}
The preceding Encryptor.java and decryptor.java implement the StreamRequestHandler API, while the CustomerInfo.java class encapsulates the service logic.
public class CustomerInfo {
# Retrieve PUB_KEY from Cloud Customer Service
private static String PUB_KEY = "your PUB_KEY";
public String encrypt(String cInfo) throws GeneralSecurityException, UnsupportedEncodingException {
PublicKey publicKey = getPubKey(PUB_KEY);
Map<String, String> res = CustomerInfoCryptoUtil.encryptByPublicKey(cInfo, publicKey);
JSONObject jsonObject = new JSONObject();
jsonObject.put("cinfo", res.get("text"));
jsonObject.put("key", res.get("key"));
return jsonObject.toJSONString();
}
public String decrypt(String params, String key) throws UnsupportedEncodingException, GeneralSecurityException {
PublicKey publicKey = getPubKey(PUB_KEY);
return CustomerInfoCryptoUtil.decryptByPublicKey(params, key, publicKey);
}
private PublicKey getPubKey(String pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64Util.decode(pubKey));
KeyFactory keyFactory;
keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(keySpec);
return key;
}
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes/lib</outputDirectory>
<includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
</plugin>
The official Function Compute documentation recommends two packaging methods, namely, maven-assembly-plugin and maven-dependency-plugin.
In this example, maven-assembly-plugin is not feasible because it cannot package the transitive dependency specified by systemPath, resulting in missing classes during the runtime. Therefore, the maven-dependency-plugin method is used instead.
Configure the template.yml file on Fun for description, and then run mvn package && fun deploy
.
ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
YunkefuSign:
Type: 'Aliyun::Serverless::Service'
Properties:
Description: 'yun ke fu Sign'
Encryptor:
Type: 'Aliyun::Serverless::Function'
Properties:
Handler: com.aliyun.fc.Encryptor::handleRequest
Runtime: java8
CodeUri: './target/yunkefu-sign-1.0-SNAPSHOT.jar'
Timeout: 60
Decryptor:
Type: 'Aliyun::Serverless::Function'
Properties:
Handler: com.aliyun.fc.Decryptor::handleRequest
Runtime: java8
CodeUri: './target/yunkefu-sign-1.0-SNAPSHOT.jar'
Timeout: 60
Using a language as a service boundary is one of the most common ways to define the boundaries for a service architecture. Function Compute supports multi-language environments and provides high scalability and availability, making it an ideal solution for supporting the multi-language architecture as a service.
Normally, developers have accumulated rich experience in familiar languages and have established a complete architecture and deployment O&M system. However, to expand the business boundary, they sometimes have to select an unfamiliar programming language and architecture. To address this challenge, Function Compute uses a single simple language to develop businesses, resolving your concerns about architecture and O&M and mitigating the developers' workload.
99 posts | 7 followers
FollowAlibaba Clouder - January 18, 2021
Alibaba Clouder - June 15, 2020
Data Geek - November 4, 2024
Alibaba Clouder - September 24, 2020
Alibaba Clouder - May 23, 2017
Alibaba Clouder - February 17, 2020
99 posts | 7 followers
FollowAlibaba Cloud Function Compute is a fully-managed event-driven compute service. It allows you to focus on writing and uploading code without the need to manage infrastructure such as servers.
Learn MoreAPI Gateway provides you with high-performance and high-availability API hosting services to deploy and release your APIs on Alibaba Cloud products.
Learn MoreMSE provides a fully managed registration and configuration center, and gateway and microservices governance capabilities.
Learn MoreVisualization, O&M-free orchestration, and Coordination of Stateful Application Scenarios
Learn MoreMore Posts by Alibaba Cloud Serverless