Deploy Microservices with Function Compute: Visitor Card of Cloud Customer Service

Challenges

Users have tried to migrate Java by themselves but encountered the following technical challenges:

  • JAR provided by Cloud Customer Service is a private Maven warehouse and cannot be accessed by the external network. Therefore, JAR must be copied to Maven for integration.
  • How should the Maven plug-in be properly configured to generate a JAR package that is supported by Function Compute?

Dependencies on Local JAR Packages

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>

Encapsulate the Handler function

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

Package

<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 maven-assembly-plugin method extracts all dependent class files and repackages them into a smaller JAR package. However, this may introduce several problems.
  • The maven-dependency-plugin method packages all dependent JAR packages to the internal lib/ directory and then packages them as nested JAR packages. During runtime, Function Compute decompresses the top-layer JAR packages.

Deploy Fun

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

Conclusion

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.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Alibaba Cloud

Alibaba Cloud

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com