Merge pull request #3 from DLive/master
Integrate demo and erlanalysis project
diff --git a/.gitignore b/.gitignore
index d1fabf5..2f5cc92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@
codecov.json
.DS_Store
doc
+target
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 63002bc..f49a4e1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,201 @@
-MIT License
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
-Copyright (c) 2018 Dlive
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+ 1. Definitions.
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
\ No newline at end of file
diff --git a/README.md b/README.md
index cf09217..4e9b3c5 100644
--- a/README.md
+++ b/README.md
@@ -30,13 +30,13 @@
Add dubblerl to rebar.config with your project
```erlang
{deps, [
- {dubboerl, {git, "http://github.com/dubboerl/dubboerl.git", {branch, "master"}}}
+ {dubboerl, {git, "https://github.com/apache/incubator-dubbo-erlang.git", {branch, "master"}}}
]}.
```
#### Step1
-Use [erlanalysis](https://github.com/dubboerl/erlanalysis) tool transfer java interface to erlang lib. And add the lib to you project app dir.
+Use [erlanalysis](./tools/erlanalysis) tool transfer java interface to erlang lib. And add the lib to you project app dir.
#### Step2
@@ -49,10 +49,10 @@
{zookeeper_list,[{"127.0.0.1",2181}]},
{application,<<"testdubboerl">>},
{consumer,[
- {<<"me.dlive.dubboservice.service.IProcessData">>,[]}
+ {<<"org.apache.dubbo.erlang.sample.service.facade.UserOperator">>,[]}
]},
{provider,[
- {scherdule_impl,scherdule_behaviour,<<"me.dlive.dubboservice.service.Scherdule">>,[]}
+ {user_impl,userOperator,<<"org.apache.dubbo.erlang.sample.service.facade.UserOperator">>,[]}
]}
]}
@@ -67,13 +67,13 @@
Call the interface method.
```erlang
-RequestPara = #testReq{name = <<"nameinfo">>,nick = <<"nickinfo">>,age = 10},
-iProcessData:queryinfo(Info).
+Request = #userInfoRequest{requestId = 123, username = "testname"},
+userOperator:queryUserInfo(Request,#{sync=> true}).
```
Sample
------
-Reference the demo project [dubboerl_demo](https://github.com/dubboerl/dubboerl_demo)
+Reference the demo project [dubboerl_demo](./samples/dubboerl_demo)
More Documents
------
diff --git a/samples/README.md b/samples/README.md
new file mode 100644
index 0000000..0a737c9
--- /dev/null
+++ b/samples/README.md
@@ -0,0 +1,30 @@
+
+## Start
+
+#### Step1
+
+Generate Java facade
+
+```
+cd dubboservice
+mvn install
+```
+
+#### Step2
+
+Generate Erlang lib by erlanalysis tool.
+
+```
+java -cp erlanalysis-1.0.jar com.ifcoder.dubboerl.analysis.ParserStart com.ifcoder.demo dubbo-service 1.2
+```
+
+#### Step3
+
+ cp dubbo-service erlang lib to dubboerl_demo
+
+#### Stpe4
+
+```
+cd dubboerl_demo
+rebar3 shell --apps "dubboerl_demo"
+```
diff --git a/samples/dubbo-sample-service/pom.xml b/samples/dubbo-sample-service/pom.xml
new file mode 100644
index 0000000..2ad87e0
--- /dev/null
+++ b/samples/dubbo-sample-service/pom.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.dubbo.erlang</groupId>
+ <artifactId>dubbo-sample-service</artifactId>
+ <version>1.3</version>
+
+ <name>dubbo-sample-service</name>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.alibaba</groupId>
+ <artifactId>dubbo</artifactId>
+ <version>2.5.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.javassist</groupId>
+ <artifactId>javassist</artifactId>
+ <version>3.18.1-GA</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.15</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.sun.jdmk</groupId>
+ <artifactId>jmxtools</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.sun.jmx</groupId>
+ <artifactId>jmxri</artifactId>
+ </exclusion>
+ <exclusion>
+ <artifactId>jms</artifactId>
+ <groupId>javax.jms</groupId>
+ </exclusion>
+ <exclusion>
+ <artifactId>mail</artifactId>
+ <groupId>javax.mail</groupId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring</artifactId>
+ <version>2.5.6.SEC03</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.6</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.9</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.6.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.101tec</groupId>
+ <artifactId>zkclient</artifactId>
+ <version>0.4</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>3.0.0</version>
+ </plugin>
+ <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
+ <plugin>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>3.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.7.0</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.20.1</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>3.0.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>2.5.2</version>
+ </plugin>
+ <plugin>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.2</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+</project>
diff --git a/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/App.java b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/App.java
new file mode 100644
index 0000000..a7a34d1
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/App.java
@@ -0,0 +1,27 @@
+package org.apache.dubbo.erlang.sample.service;
+
+import org.apache.dubbo.erlang.sample.service.bean.UserInfo;
+import org.apache.dubbo.erlang.sample.service.facade.UserOperator;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.io.IOException;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args ) throws IOException {
+ System.out.println("将要监听服务");
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
+ new String[] { "applicationProvider.xml" });
+ context.start();
+ UserOperator userOperator = (UserOperator) context.getBean("userInterface");
+ UserInfo result = userOperator.getUserInfo("hh-bb");
+ System.out.println("result:" + result.getUserName());
+
+ System.out.println("按任意键退出");
+ System.in.read();
+ }
+}
diff --git a/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/AppListMain.java b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/AppListMain.java
new file mode 100644
index 0000000..68f128c
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/AppListMain.java
@@ -0,0 +1,24 @@
+package org.apache.dubbo.erlang.sample.service;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import java.io.IOException;
+
+/**
+ * Created by dlive on 2018/9/12.
+ */
+public class AppListMain {
+
+ public static void main( String[] args ) throws IOException {
+ System.out.println("将要监听服务");
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
+ new String[] { "applicationProvider.xml" });
+ context.start();
+// UserOperator user = (UserOperator) context.getBean("userInterface");
+// UserRes result = user.queryUserList("listquery");
+// System.out.println("result:" + result.getUserlist().get(0).getUserName());
+
+ System.out.println("按任意键退出");
+ System.in.read();
+ }
+}
diff --git a/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserInfo.java b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserInfo.java
new file mode 100644
index 0000000..0c6725f
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserInfo.java
@@ -0,0 +1,34 @@
+package org.apache.dubbo.erlang.sample.service.bean;
+
+import java.io.Serializable;
+
+public class UserInfo implements Serializable {
+
+ private String userId;
+ private String userName;
+ private Integer userAge;
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public Integer getUserAge() {
+ return userAge;
+ }
+
+ public void setUserAge(Integer userAge) {
+ this.userAge = userAge;
+ }
+}
diff --git a/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserInfoRequest.java b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserInfoRequest.java
new file mode 100644
index 0000000..3afbea4
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserInfoRequest.java
@@ -0,0 +1,25 @@
+package org.apache.dubbo.erlang.sample.service.bean;
+
+/**
+ * Created by dlive on 2018/9/12.
+ */
+public class UserInfoRequest {
+ public String requestId;
+ public String username;
+
+ public void setRequestId(String requestId) {
+ this.requestId = requestId;
+ }
+
+ public String getRequestId() {
+ return requestId;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+}
diff --git a/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserRes.java b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserRes.java
new file mode 100644
index 0000000..9a22786
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/bean/UserRes.java
@@ -0,0 +1,20 @@
+package org.apache.dubbo.erlang.sample.service.bean;
+
+import java.util.List;
+
+/**
+ * Created by dlive on 2018/9/12.
+ */
+public class UserRes {
+ private String message;
+ private Integer code;
+ private List<UserInfo> userlist;
+
+ public List<UserInfo> getUserlist() {
+ return userlist;
+ }
+
+ public void setUserlist(List<UserInfo> userlist) {
+ this.userlist = userlist;
+ }
+}
diff --git a/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/facade/UserOperator.java b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/facade/UserOperator.java
new file mode 100644
index 0000000..a9439d8
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/facade/UserOperator.java
@@ -0,0 +1,13 @@
+package org.apache.dubbo.erlang.sample.service.facade;
+
+import org.apache.dubbo.erlang.sample.service.bean.UserInfo;
+import org.apache.dubbo.erlang.sample.service.bean.UserInfoRequest;
+import org.apache.dubbo.erlang.sample.service.bean.UserRes;
+
+public interface UserOperator {
+ public String genUserId();
+ public UserInfo getUserInfo(String userid);
+ public UserInfo queryUserInfo(UserInfoRequest request);
+ public UserRes queryUserList(String info);
+
+}
diff --git a/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/impl/UserOperatorImpl.java b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/impl/UserOperatorImpl.java
new file mode 100644
index 0000000..e482c5b
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/java/org/apache/dubbo/erlang/sample/service/impl/UserOperatorImpl.java
@@ -0,0 +1,39 @@
+package org.apache.dubbo.erlang.sample.service.impl;
+
+import org.apache.dubbo.erlang.sample.service.bean.UserInfo;
+import org.apache.dubbo.erlang.sample.service.bean.UserInfoRequest;
+import org.apache.dubbo.erlang.sample.service.bean.UserRes;
+import org.apache.dubbo.erlang.sample.service.facade.UserOperator;
+
+public class UserOperatorImpl implements UserOperator {
+
+ @Override
+ public String genUserId() {
+ return "userid-123";
+ }
+
+ @Override
+ public UserInfo getUserInfo(String userid) {
+ UserInfo info = new UserInfo();
+ info.setUserAge(10);
+ info.setUserId("1");
+ info.setUserName("testname");
+ return info;
+ }
+
+ @Override
+ public UserInfo queryUserInfo(UserInfoRequest request) {
+
+ System.out.println("request:"+request.getRequestId());
+ UserInfo info = new UserInfo();
+ info.setUserAge(99);
+ info.setUserId("id123");
+ info.setUserName("中文姓名");
+ return info;
+ }
+
+ @Override
+ public UserRes queryUserList(String info) {
+ return null;
+ }
+}
diff --git a/samples/dubbo-sample-service/src/main/resources/applicationProvider.xml b/samples/dubbo-sample-service/src/main/resources/applicationProvider.xml
new file mode 100644
index 0000000..f6991ce
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/resources/applicationProvider.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
+ <dubbo:application name="hello-world" /><!-- 注册地址 -->
+ <dubbo:registry address="zookeeper://127.0.0.1:2181" />
+ <dubbo:protocol name="dubbo" port="20880" />
+
+
+
+ <dubbo:consumer check="false" timeout="300000" id="dubboConsumerConfig" retries="0"/>
+
+ <bean id="userService" class="org.apache.dubbo.erlang.sample.service.impl.UserOperatorImpl" />
+ <dubbo:service interface="org.apache.dubbo.erlang.sample.service.facade.UserOperator" ref="userService"/>
+
+<!-- <dubbo:reference id="userInterface" interface="UserOperator" retries="0" />-->
+</beans>
diff --git a/samples/dubbo-sample-service/src/main/resources/log4j.properties b/samples/dubbo-sample-service/src/main/resources/log4j.properties
new file mode 100644
index 0000000..d6e4cfe
--- /dev/null
+++ b/samples/dubbo-sample-service/src/main/resources/log4j.properties
@@ -0,0 +1,8 @@
+log4j.rootLogger=DEBUG,console
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=DEBUG
+#log4j.appender.console.ImmediateFlush=true
+#log4j.appender.console.Target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] %m%n
diff --git a/samples/dubbo-sample-service/src/test/java/org/apache/dubbo/erlang/sample/service/AppTest.java b/samples/dubbo-sample-service/src/test/java/org/apache/dubbo/erlang/sample/service/AppTest.java
new file mode 100644
index 0000000..93788df
--- /dev/null
+++ b/samples/dubbo-sample-service/src/test/java/org/apache/dubbo/erlang/sample/service/AppTest.java
@@ -0,0 +1,20 @@
+package org.apache.dubbo.erlang.sample.service;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+{
+ /**
+ * Rigorous Test :-)
+ */
+ @Test
+ public void shouldAnswerWithTrue()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/samples/dubboerl_demo/README.md b/samples/dubboerl_demo/README.md
new file mode 100644
index 0000000..5ec4ad4
--- /dev/null
+++ b/samples/dubboerl_demo/README.md
@@ -0,0 +1,14 @@
+dubboerl_demo
+=====
+
+An OTP application
+
+Build
+-----
+
+ $ rebar3 compile
+
+
+Start
+-----
+ ./rebar3 shell --apps "dubboerl_demo"
\ No newline at end of file
diff --git a/samples/dubboerl_demo/apps/dubbo_sample_service/include/dubbo_sample_service.hrl b/samples/dubboerl_demo/apps/dubbo_sample_service/include/dubbo_sample_service.hrl
new file mode 100644
index 0000000..2bd8bdf
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubbo_sample_service/include/dubbo_sample_service.hrl
@@ -0,0 +1,13 @@
+
+-record(userInfoRequest,{
+ username ::list(),
+ requestId ::list()}).
+
+-record(userRes,{
+ userlist ::[]}).
+
+-record(userInfo,{
+ userId ::list(),
+ userName ::list(),
+ userAge ::integer()}).
+
diff --git a/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service.app.src b/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service.app.src
new file mode 100644
index 0000000..156953f
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service.app.src
@@ -0,0 +1,17 @@
+{application, dubbo_sample_service,
+[
+ {description, "An OTP application"},
+ {vsn, "1.3"},
+ {registered, []},
+ {mod, { dubbo_sample_service_app, []}},
+ {applications,
+ [kernel,
+ stdlib,
+ dubboerl
+ ]},
+ {env,[]},
+ {modules, []},
+ {maintainers, []},
+ {licenses, []},
+ {links, []}
+]}.
diff --git a/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_app.erl b/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_app.erl
new file mode 100644
index 0000000..5360d7f
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_app.erl
@@ -0,0 +1,39 @@
+%%%-------------------------------------------------------------------
+%% @doc dubbo_sample_service public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(dubbo_sample_service_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+-include("dubbo_sample_service.hrl").
+
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+ register_type_list(),
+ dubbo_sample_service_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+ ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
+
+
+register_type_list()->
+ List = dubbo_sample_service_type_list:get_list(),
+ lists:map(
+ fun({NativeType,ForeignType,Fields}) ->
+ dubbo_type_transfer:pre_process_typedef(NativeType,ForeignType,Fields)
+ end,List),
+ ok.
\ No newline at end of file
diff --git a/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_sup.erl b/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_sup.erl
new file mode 100644
index 0000000..a7e7ead
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_sup.erl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc dubbo_sample_service top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(dubbo_sample_service_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+%%====================================================================
+%% API functions
+%%====================================================================
+
+start_link() ->
+ supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+
+%%====================================================================
+%% Supervisor callbacks
+%%====================================================================
+
+%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
+init([]) ->
+ {ok, { {one_for_all, 0, 1}, []} }.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_type_list.erl b/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_type_list.erl
new file mode 100644
index 0000000..ce46bef
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubbo_sample_service/src/dubbo_sample_service_type_list.erl
@@ -0,0 +1,15 @@
+-module(dubbo_sample_service_type_list).
+
+%% API
+-export([register_type_list/0,get_list/0]).
+
+-include("dubbo_sample_service.hrl").
+
+get_list()->
+ [
+ {userInfoRequest,<<"org.apache.dubbo.erlang.sample.service.bean.UserInfoRequest">>,record_info(fields,userInfoRequest)},
+ {userRes,<<"org.apache.dubbo.erlang.sample.service.bean.UserRes">>,record_info(fields,userRes)},
+ {userInfo,<<"org.apache.dubbo.erlang.sample.service.bean.UserInfo">>,record_info(fields,userInfo)} ].
+
+register_type_list()->
+ ok.
\ No newline at end of file
diff --git a/samples/dubboerl_demo/apps/dubbo_sample_service/src/userOperator.erl b/samples/dubboerl_demo/apps/dubbo_sample_service/src/userOperator.erl
new file mode 100644
index 0000000..b92ca62
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubbo_sample_service/src/userOperator.erl
@@ -0,0 +1,162 @@
+-module(userOperator).
+
+-include_lib("dubboerl/include/dubbo.hrl").
+-include_lib("dubboerl/include/hessian.hrl").
+
+-define(CURRENT_CLASS_NAME,<<"org.apache.dubbo.erlang.sample.service.facade.UserOperator"/utf8>>).
+-define(CURRENT_CLASS_VERSION,<<"0.0.0"/utf8>>).
+
+-include("dubbo_sample_service.hrl").
+
+
+
+
+%% API
+-export([
+ getUserInfo/1,
+ getUserInfo/2,
+ genUserId/0,
+ genUserId/1,
+ queryUserInfo/1,
+ queryUserInfo/2,
+ queryUserList/1,
+ queryUserList/2]).
+
+-export([get_method_999_list/0]).
+
+%% behaviour
+-callback getUserInfo(Arg0::list())-> #userInfo{}.
+-callback genUserId()-> list().
+-callback queryUserInfo(Arg0::#userInfoRequest{})-> #userInfo{}.
+-callback queryUserList(Arg0::list())-> #userRes{}.
+
+get_method_999_list()->
+ [
+ getUserInfo,
+ genUserId,
+ queryUserInfo,
+ queryUserList].
+
+
+
+-spec getUserInfo(Arg0::list())->
+ {ok,reference()}|
+ {ok,reference(),Data::#userInfo{},RpcContent::list()}|
+ {error,Reason::timeout|no_provider|any()}.
+getUserInfo(Arg0)->
+ getUserInfo(Arg0 ,#{}).
+
+getUserInfo(Arg0, RequestOption)->
+
+ Data = #dubbo_rpc_invocation{
+ className = ?CURRENT_CLASS_NAME,
+ classVersion = ?CURRENT_CLASS_VERSION,
+ methodName = <<"getUserInfo">>,
+ parameterDesc = <<"Ljava/lang/String;"/utf8>>,
+ parameterTypes = [
+ #type_def{foreign_type = <<"java.lang.String">>,
+ native_type = string,
+ fieldnames = []}
+ ],
+ parameters = [
+ Arg0
+ ],
+ attachments = [
+ {<<"path">>, ?CURRENT_CLASS_NAME},
+ {<<"interface">> , ?CURRENT_CLASS_NAME}
+ ]
+ },
+ Request = dubbo_adapter:reference(Data),
+ dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
+
+-spec genUserId()->
+ {ok,reference()}|
+ {ok,reference(),Data::list(),RpcContent::list()}|
+ {error,Reason::timeout|no_provider|any()}.
+genUserId()->
+ genUserId( #{}).
+
+genUserId( RequestOption)->
+
+ Data = #dubbo_rpc_invocation{
+ className = ?CURRENT_CLASS_NAME,
+ classVersion = ?CURRENT_CLASS_VERSION,
+ methodName = <<"genUserId">>,
+ parameterDesc = <<""/utf8>>,
+ parameterTypes = [
+
+ ],
+ parameters = [
+
+ ],
+ attachments = [
+ {<<"path">>, ?CURRENT_CLASS_NAME},
+ {<<"interface">> , ?CURRENT_CLASS_NAME}
+ ]
+ },
+ Request = dubbo_adapter:reference(Data),
+ dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
+
+-spec queryUserInfo(Arg0::#userInfoRequest{})->
+ {ok,reference()}|
+ {ok,reference(),Data::#userInfo{},RpcContent::list()}|
+ {error,Reason::timeout|no_provider|any()}.
+queryUserInfo(Arg0)->
+ queryUserInfo(Arg0 ,#{}).
+
+queryUserInfo(Arg0, RequestOption)->
+
+ Data = #dubbo_rpc_invocation{
+ className = ?CURRENT_CLASS_NAME,
+ classVersion = ?CURRENT_CLASS_VERSION,
+ methodName = <<"queryUserInfo">>,
+ parameterDesc = <<"Lorg/apache/dubbo/erlang/sample/service/bean/UserInfoRequest;"/utf8>>,
+ parameterTypes = [
+ #type_def{foreign_type = <<"org.apache.dubbo.erlang.sample.service.bean.UserInfoRequest">>,
+ native_type = userInfoRequest,
+ fieldnames = record_info(fields,userInfoRequest)}
+ ],
+ parameters = [
+ Arg0
+ ],
+ attachments = [
+ {<<"path">>, ?CURRENT_CLASS_NAME},
+ {<<"interface">> , ?CURRENT_CLASS_NAME}
+ ]
+ },
+ Request = dubbo_adapter:reference(Data),
+ dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
+
+-spec queryUserList(Arg0::list())->
+ {ok,reference()}|
+ {ok,reference(),Data::#userRes{},RpcContent::list()}|
+ {error,Reason::timeout|no_provider|any()}.
+queryUserList(Arg0)->
+ queryUserList(Arg0 ,#{}).
+
+queryUserList(Arg0, RequestOption)->
+
+ Data = #dubbo_rpc_invocation{
+ className = ?CURRENT_CLASS_NAME,
+ classVersion = ?CURRENT_CLASS_VERSION,
+ methodName = <<"queryUserList">>,
+ parameterDesc = <<"Ljava/lang/String;"/utf8>>,
+ parameterTypes = [
+ #type_def{foreign_type = <<"java.lang.String">>,
+ native_type = string,
+ fieldnames = []}
+ ],
+ parameters = [
+ Arg0
+ ],
+ attachments = [
+ {<<"path">>, ?CURRENT_CLASS_NAME},
+ {<<"interface">> , ?CURRENT_CLASS_NAME}
+ ]
+ },
+ Request = dubbo_adapter:reference(Data),
+ dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
diff --git a/samples/dubboerl_demo/apps/dubboerl_demo/src/api_gateway_handle.erl b/samples/dubboerl_demo/apps/dubboerl_demo/src/api_gateway_handle.erl
new file mode 100644
index 0000000..b89efb8
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubboerl_demo/src/api_gateway_handle.erl
@@ -0,0 +1,77 @@
+%%%-------------------------------------------------------------------
+%%% @author dlive
+%%% @copyright (C) 2018, <COMPANY>
+%%% @doc
+%%%
+%%% @end
+%%% Created : 28. Feb 2018 10:57 PM
+%%%-------------------------------------------------------------------
+-module(api_gateway_handle).
+-author("dlive").
+
+-include_lib("dubbo_sample_service/include/dubbo_sample_service.hrl").
+
+-export([init/2]).
+-export([content_types_provided/2]).
+-export([hello_to_html/2]).
+-export([hello_to_json/2]).
+-export([hello_to_text/2]).
+-export([info/3]).
+
+%%init(Req, Opts) ->
+%% {cowboy_rest, Req, Opts}.
+init(Req, State) ->
+ io:format("get loop init ~n"),
+ request_to_dubbo(Req,State),
+ {cowboy_loop, Req, State}.
+
+content_types_provided(Req, State) ->
+ {[
+ {<<"text/html">>, hello_to_html},
+ {<<"application/json">>, hello_to_json},
+ {<<"text/plain">>, hello_to_text}
+ ], Req, State}.
+
+hello_to_html(Req, State) ->
+ Body = <<"<html>
+<head>
+ <meta charset=\"utf-8\">
+ <title>REST Hello World!</title>
+</head>
+<body>
+ <p>REST Hello World as HTML!</p>
+</body>
+</html>">>,
+ {Body, Req, State}.
+
+hello_to_json(Req, State) ->
+ Body = <<"{\"rest\": \"Hello World!\"}">>,
+ {Body, Req, State}.
+
+hello_to_text(Req, State) ->
+ {<<"REST Hello World as text!">>, Req, State}.
+
+
+info({reply, Body}, Req, State) ->
+ cowboy_req:reply(200, #{}, Body, Req),
+ {stop, Req, State};
+info({'$gen_cast',{msg_back,Ref,Response,RpcContent}},Req,State)->
+ io:format("get msg_back ~p~n",[Response]),
+ Body = <<"<html>
+<head>
+ <meta charset=\"utf-8\">
+ <title>REST Hello World!</title>
+</head>
+<body>
+ <p>REST Hello World as HTML!</p>
+</body>
+</html>">>,
+ Req2=cowboy_req:reply(200, #{}, Body, Req),
+ {stop, Req2, State};
+info(_Msg, Req, State) ->
+ io:format("get info ~p~n",[_Msg]),
+ {ok, Req, State, hibernate}.
+
+request_to_dubbo(Req, State)->
+ userOperator:queryUserInfo(#userInfoRequest{username = "name",requestId = "111"},#{sync=> true}),
+ ok.
diff --git a/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo.app.src b/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo.app.src
new file mode 100644
index 0000000..07e36f1
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo.app.src
@@ -0,0 +1,19 @@
+{application, dubboerl_demo,
+ [{description, "An OTP application"},
+ {vsn, "0.1.0"},
+ {registered, []},
+ {mod, { dubboerl_demo_app, []}},
+ {applications,
+ [kernel,
+ stdlib,
+ recon,
+ observer_cli,
+ dubbo_sample_service
+ ]},
+ {env,[]},
+ {modules, []},
+
+ {maintainers, []},
+ {licenses, ["Apache 2.0"]},
+ {links, []}
+ ]}.
diff --git a/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo_app.erl b/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo_app.erl
new file mode 100644
index 0000000..0dee318
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo_app.erl
@@ -0,0 +1,48 @@
+%%%-------------------------------------------------------------------
+%% @doc dubboerl_demo public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(dubboerl_demo_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1,test_fun/0]).
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+ start_app(),
+ dubboerl:init(),
+ start_web(),
+ dubboerl_demo_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+ ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
+start_app()->
+ application:ensure_all_started(dubboerl),
+ application:ensure_all_started(dubbo_sample_service),
+ application:ensure_all_started(cowboy),
+ ok.
+
+start_web()->
+ Dispatch = cowboy_router:compile([
+ {'_', [
+ {"/", api_gateway_handle, []}
+ ]}
+ ]),
+ {ok, _} = cowboy:start_clear(http, [{port,9090}], #{
+ env => #{dispatch => Dispatch}
+ }),
+ ok.
+
+test_fun()->
+ ok1.
\ No newline at end of file
diff --git a/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo_sup.erl b/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo_sup.erl
new file mode 100644
index 0000000..ca6f672
--- /dev/null
+++ b/samples/dubboerl_demo/apps/dubboerl_demo/src/dubboerl_demo_sup.erl
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc dubboerl_demo top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(dubboerl_demo_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+%%====================================================================
+%% API functions
+%%====================================================================
+
+start_link() ->
+ supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+
+%%====================================================================
+%% Supervisor callbacks
+%%====================================================================
+
+%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
+init([]) ->
+ {ok, { {one_for_all, 0, 1}, []} }.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/samples/dubboerl_demo/config/sys.config b/samples/dubboerl_demo/config/sys.config
new file mode 100644
index 0000000..153810e
--- /dev/null
+++ b/samples/dubboerl_demo/config/sys.config
@@ -0,0 +1,24 @@
+[
+ {dubboerl_demo, []},
+ {dubboerl,[
+ {registry,true},
+ {zookeeper_list,[{"127.0.0.1",2181}]},
+ {application,<<"dubboerl_demo">>},
+ {protocol,hessian},
+ {port,20881},
+ {consumer,[
+ {<<"org.apache.dubbo.erlang.sample.service.facade.UserOperator">>,[]}
+ ]},
+ {provider,[
+ ]}
+
+ ]},
+ {lager, [
+ {log_root, "./logs"},
+ {handlers, [
+ {lager_console_backend, debug},
+ {lager_file_backend, [{file, "error.log"}, {level, error}]},
+ {lager_file_backend, [{file, "console.log"}, {level, debug}]}
+ ]}
+ ]}
+].
diff --git a/samples/dubboerl_demo/config/vm.args b/samples/dubboerl_demo/config/vm.args
new file mode 100644
index 0000000..7e10276
--- /dev/null
+++ b/samples/dubboerl_demo/config/vm.args
@@ -0,0 +1,6 @@
+-sname dubboerl_demo
+
+-setcookie dubboerl_demo_cookie
+
++K true
++A30
diff --git a/samples/dubboerl_demo/nohup.out b/samples/dubboerl_demo/nohup.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/samples/dubboerl_demo/nohup.out
diff --git a/samples/dubboerl_demo/rebar.config b/samples/dubboerl_demo/rebar.config
new file mode 100644
index 0000000..ec01605
--- /dev/null
+++ b/samples/dubboerl_demo/rebar.config
@@ -0,0 +1,27 @@
+{erl_opts, [debug_info]}.
+{deps, [
+ {recon, ".*", {git, "https://github.com/ferd/recon.git", {tag, "2.3.2"}}},
+ {observer_cli, ".*", {git, "https://github.com/zhongwencool/observer_cli.git", {tag, "1.2.1"}}},
+ {cowboy, ".*", {git, "https://github.com/ninenines/cowboy.git", {tag, "2.3.0"}}},
+ {dubboerl, ".*", {git, "https://github.com/apache/incubator-dubbo-erlang.git", {branch, "master"}}}
+]}.
+
+{plugins, [rebar3_auto]}.
+
+{relx, [{release, {dubboerl_demo, "0.1.0"},
+ [dubboerl_demo,
+ sasl]},
+
+ {sys_config, "./config/sys.config"},
+ {vm_args, "./config/vm.args"},
+
+ {dev_mode, true},
+ {include_erts, false},
+
+ {extended_start_script, true}]
+}.
+
+{profiles, [{prod, [{relx, [{dev_mode, false},
+ {include_erts, true}]}]
+}]
+}.
diff --git a/samples/dubboerl_demo/rebar.lock b/samples/dubboerl_demo/rebar.lock
new file mode 100644
index 0000000..584acf9
--- /dev/null
+++ b/samples/dubboerl_demo/rebar.lock
@@ -0,0 +1,38 @@
+{"1.1.0",
+[{<<"cowboy">>,
+ {git,"https://github.com/ninenines/cowboy.git",
+ {ref,"a7b06f2e138c0c03c2511ed9fe6803fc9ebf3401"}},
+ 0},
+ {<<"cowlib">>,
+ {git,"https://github.com/ninenines/cowlib",
+ {ref,"b6381527831c5ebb74759e119a517b7d22d4b23a"}},
+ 1},
+ {<<"dubboerl">>,
+ {git,"https://github.com/apache/incubator-dubbo-erlang.git",
+ {ref,"aea1facd9cf9cc7f9427329473662d8b5963e489"}},
+ 0},
+ {<<"erlzk">>,
+ {git,"https://github.com/huaban/erlzk.git",
+ {ref,"aa7190ee2343ac1341cea3edc9b9eea36c591708"}},
+ 1},
+ {<<"jiffy">>,{pkg,<<"jiffy">>,<<"0.15.1">>},1},
+ {<<"observer_cli">>,
+ {git,"https://github.com/zhongwencool/observer_cli.git",
+ {ref,"4d5f96762bb525b4f857109c10a7d4d53af1a029"}},
+ 0},
+ {<<"poolboy">>,
+ {git,"https://github.com/devinus/poolboy.git",
+ {ref,"3bb48a893ff5598f7c73731ac17545206d259fac"}},
+ 1},
+ {<<"ranch">>,
+ {git,"https://github.com/ninenines/ranch",
+ {ref,"55c2a9d623454f372a15e99721a37093d8773b48"}},
+ 1},
+ {<<"recon">>,
+ {git,"https://github.com/ferd/recon.git",
+ {ref,"fcc1a7db6d367234171ab24a3d1762f94e57ff22"}},
+ 0}]}.
+[
+{pkg_hash,[
+ {<<"jiffy">>, <<"BE83B09388DA1A6C7E798207C9D6A1C4D71BB95FCC387D37D35861788F49AB97">>}]}
+].
diff --git a/src/dubbo_heartbeat.erl b/src/dubbo_heartbeat.erl
index 97edbd2..e84deed 100644
--- a/src/dubbo_heartbeat.erl
+++ b/src/dubbo_heartbeat.erl
@@ -17,7 +17,7 @@
generate_request(undefined,NeedResponse)->
RequestId = dubbo_id_generator:gen_id(),
generate_request(RequestId,NeedResponse);
-generate_request(RequestId,_NeedResponse)->
- Req = #dubbo_request{is_event = true,is_twoway = true,mid = RequestId,data = undefined,mversion= <<"2.0.0">>},
+generate_request(RequestId,NeedResponse)->
+ Req = #dubbo_request{is_event = true,is_twoway = NeedResponse,mid = RequestId,data = undefined,mversion= <<"2.0.0">>},
{ok,Bin} = dubbo_codec:encode_request(Req),
{ok,Bin}.
\ No newline at end of file
diff --git a/src/dubbo_netty_client.erl b/src/dubbo_netty_client.erl
index e5dc72c..754c8c5 100644
--- a/src/dubbo_netty_client.erl
+++ b/src/dubbo_netty_client.erl
@@ -349,29 +349,28 @@
process_data(Data,State)->
- TmpTime = time_util:timestamp_ms(),
<<Header:16/binary,RestData/binary>> = Data,
case dubbo_codec:decode_header(Header) of
{ok,response,ResponseInfo}->
- %%心跳包的回应,是否会造成错误
- dubbo_traffic_control:decr_count(State#state.host_flag),
- case get_earse_request_info(ResponseInfo#dubbo_response.mid) of
- undefined->
- logger:error("dubbo response can't find request data,response ~p",[ResponseInfo]);
- {SourcePid,Ref,_RequestState} ->
- {ok,Res} = dubbo_codec:decode_response(ResponseInfo,RestData),
-
- logger:info("got one response mid ~p, is_event ~p state ~p",[Res#dubbo_response.mid,Res#dubbo_response.is_event,Res#dubbo_response.state]),
- case Res#dubbo_response.is_event of
- false ->
- %% todo rpccontent need merge response with request
- RpcContent=[],
- ResponseData = dubbo_type_transfer:response_to_native(Res),
- gen_server:cast(SourcePid,{response_process,Ref,RpcContent,ResponseData});
- _->
- ok
- end
- end,
+ process_response(ResponseInfo#dubbo_response.is_event,ResponseInfo,RestData,State),
+%% dubbo_traffic_control:decr_count(State#state.host_flag),
+%% case get_earse_request_info(ResponseInfo#dubbo_response.mid) of
+%% undefined->
+%% logger:error("dubbo response can't find request data,response ~p",[ResponseInfo]);
+%% {SourcePid,Ref,_RequestState} ->
+%% {ok,Res} = dubbo_codec:decode_response(ResponseInfo,RestData),
+%%
+%% logger:info("got one response mid ~p, is_event ~p state ~p",[Res#dubbo_response.mid,Res#dubbo_response.is_event,Res#dubbo_response.state]),
+%% case Res#dubbo_response.is_event of
+%% false ->
+%% %% todo rpccontent need merge response with request
+%% RpcContent=[],
+%% ResponseData = dubbo_type_transfer:response_to_native(Res),
+%% gen_server:cast(SourcePid,{response_process,Ref,RpcContent,ResponseData});
+%% _->
+%% ok
+%% end
+%% end,
{ok,State};
{ok,request,RequestInfo}->
{ok,Req} = dubbo_codec:decode_request(RequestInfo,RestData),
@@ -386,18 +385,26 @@
%% @doc process event
-spec process_response(IsEvent::boolean(),#dubbo_response{},#state{},term())->ok.
-process_response(false,Response,State,TmpTime)->
+process_response(false,ResponseInfo,RestData,State)->
dubbo_traffic_control:decr_count(State#state.host_flag),
- case get_earse_request_info(Response#dubbo_response.mid) of
+ case get_earse_request_info(ResponseInfo#dubbo_response.mid) of
undefined->
- logger:error("dubbo response can't find request data,response ~p",[Response]);
- {SourcePid,Ref,RequestState} ->
- RpcContent=[],
- gen_server:cast(SourcePid,{msg_back,Ref,Response,RpcContent,RequestState})
+ logger:error("dubbo response can't find request data,response ~p",[ResponseInfo]);
+ {SourcePid,Ref,_RequestState} ->
+ {ok,Res} = dubbo_codec:decode_response(ResponseInfo,RestData),
+ logger:info("got one response mid ~p, is_event ~p state ~p",[Res#dubbo_response.mid,Res#dubbo_response.is_event,Res#dubbo_response.state]),
+ case Res#dubbo_response.is_event of
+ false ->
+ %% todo rpccontent need merge response with request
+ RpcContent=[],
+ ResponseData = dubbo_type_transfer:response_to_native(Res),
+ gen_server:cast(SourcePid,{response_process,Ref,RpcContent,ResponseData});
+ _->
+ ok
+ end
end,
{ok,State};
-process_response(true,Response,State,TmpTime)->
-
+process_response(true,_ResponseInfo,_RestData,State)->
{ok,State}.
process_request(true,Request,State)->
diff --git a/tools/erlanalysis/.gitignore b/tools/erlanalysis/.gitignore
new file mode 100644
index 0000000..e772e34
--- /dev/null
+++ b/tools/erlanalysis/.gitignore
@@ -0,0 +1,20 @@
+_*
+.eunit
+*.o
+*.beam
+*.plt
+*.swp
+*.swo
+.erlang.cookie
+ebin
+log
+erl_crash.dump
+.rebar
+logs
+_build
+.idea
+.rebar
+target
+genProjectDir
+mavenDown
+*.log
diff --git a/tools/erlanalysis/README.md b/tools/erlanalysis/README.md
new file mode 100644
index 0000000..6641cc1
--- /dev/null
+++ b/tools/erlanalysis/README.md
@@ -0,0 +1,14 @@
+# erlanalysis
+parse dubbo interface to erlang lib
+
+## Usage
+
+### Step1
+ mvn pacakge -Dmaven.skip.test=true
+
+### Steps2
+```
+java -jar target/erlanalysis-1.0.jar groupId artifactId version
+## example:
+## java -jar target/erlanalysis-1.0.jar org.apache.dubbo.erlang dubbo-sample-service 1.3
+```
\ No newline at end of file
diff --git a/tools/erlanalysis/pom.xml b/tools/erlanalysis/pom.xml
new file mode 100644
index 0000000..9b0dfcb
--- /dev/null
+++ b/tools/erlanalysis/pom.xml
@@ -0,0 +1,97 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>org.apache.dubbo.erlang</groupId>
+ <artifactId>erlanalysis</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+
+ <name>erlanalysis</name>
+ <url>https://github.com/apache/incubator-dubbo-erlang</url>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.caucho</groupId>
+ <artifactId>hessian</artifactId>
+ <version>3.1.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.7.25</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.25</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-invoker</artifactId>
+ <version>2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.16</version>
+ </dependency>
+ <dependency>
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm-all</artifactId>
+ <version>5.2</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.velocity</groupId>
+ <artifactId>velocity</artifactId>
+ <version>1.7</version>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>8</source>
+ <target>8</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <archive>
+ <manifest>
+ <mainClass>org.apache.dubbo.erlang.analysis.Start</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ <executions>
+ <execution>
+ <id>make-assembly</id>
+ <phase>package</phase>
+ <goals>
+ <goal>assembly</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/App.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/App.java
new file mode 100644
index 0000000..9362bc0
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/App.java
@@ -0,0 +1,67 @@
+package org.apache.dubbo.erlang.analysis;
+
+import com.caucho.hessian.io.HessianInput;
+import com.caucho.hessian.io.HessianOutput;
+import org.apache.dubbo.erlang.analysis.parse.InterfaceParse;
+import org.apache.dubbo.erlang.analysis.erltool.UserInfo;
+
+import java.io.*;
+
+import static java.lang.System.exit;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void writesome() throws IOException {
+ UserInfo user=new UserInfo();
+ user.setAge(10);
+ user.setUsername("userabc");
+ user.setPassword("password");
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ HessianOutput ho = new HessianOutput(os);
+ ho.writeObject(user);
+
+ FileOutputStream out = new FileOutputStream("/tmp/hessian.data");
+ out.write(os.toByteArray());
+ out.flush();
+ out.close();
+
+ }
+
+ public static void readsome() throws IOException {
+ FileInputStream input = new FileInputStream("/tmp/hessianw.data");
+ byte[] buffer = new byte[input.available()];
+ input.read(buffer);
+
+ ByteArrayInputStream is = new ByteArrayInputStream(buffer);
+ HessianInput hi = new HessianInput(is);
+ Object obj = hi.readObject();
+ System.out.println("obj:"+obj);
+ UserInfo user = (UserInfo)obj;
+ System.out.println("user:"+user);
+ }
+ public static void main( String[] args ){
+ if (args.length<3){
+ System.out.println("please input args: group artifactid version");
+ exit(1);
+ }
+ String group=args[0];
+ String artifactid=args[1];
+ String version = args[2];
+ System.out.println("will parse facade "+ group+":"+artifactid+":"+version);
+ InterfaceParse parser = new InterfaceParse();
+ parser.parse(group,artifactid,version);
+//
+// try {
+//// readsome();
+// writesome();
+// } catch (IOException e) {
+// e.printStackTrace();
+// }
+// System.out.println( "Hello World!" );
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/Start.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/Start.java
new file mode 100644
index 0000000..f968517
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/Start.java
@@ -0,0 +1,19 @@
+package org.apache.dubbo.erlang.analysis;
+
+import org.apache.dubbo.erlang.analysis.parse.InterfaceParse;
+
+public class Start {
+
+
+ public static void main(String[] args) {
+ if (args.length < 3) {
+ System.out.println("please input groupId artifactId version");
+ return;
+ }
+ String groupId = args[0];
+ String artifactId = args[1];
+ String version = args[2];
+ InterfaceParse parser = new InterfaceParse();
+ parser.parse(groupId, artifactId, version);
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/erltool/UserInfo.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/erltool/UserInfo.java
new file mode 100644
index 0000000..d4651d9
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/erltool/UserInfo.java
@@ -0,0 +1,40 @@
+package org.apache.dubbo.erlang.analysis.erltool;
+
+import java.io.Serializable;
+
+/**
+ * Created by dlive on 16/9/29.
+ */
+public class UserInfo implements Serializable {
+ private String username;
+ private Integer age;
+ private String password;
+
+ public UserInfo(){
+
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/generater/ErlProjectGenerater.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/generater/ErlProjectGenerater.java
new file mode 100644
index 0000000..638960e
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/generater/ErlProjectGenerater.java
@@ -0,0 +1,202 @@
+package org.apache.dubbo.erlang.analysis.generater;
+
+import org.apache.dubbo.erlang.analysis.parse.CommonTypeInfo;
+import org.apache.dubbo.erlang.analysis.parse.InterfaceInfo;
+
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+
+import java.io.*;
+import java.util.List;
+
+/**
+ * Created by dlive on 22/02/2018.
+ */
+public class ErlProjectGenerater {
+ private VelocityEngine ve = new VelocityEngine();
+
+ private ProjectInfo projectInfo;
+ private String projectSaveDir;
+ private String projectSrcDir;
+ private String projectIncludeDir;
+ public ErlProjectGenerater(ProjectInfo projectInfo){
+ this.projectInfo=projectInfo;
+
+ ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
+ ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
+ ve.init();
+ makeProjectDir();
+
+ }
+ public void genProject(List<InterfaceInfo> list_interfaces){
+ for (InterfaceInfo interfaceItem : list_interfaces) {
+ genInterface(interfaceItem);
+ }
+ genProjectCommonFile();
+ genProjectIncludeInfo();
+ genProjectTypeList();
+ }
+
+ private boolean genInterface(InterfaceInfo interfaceItem){
+ // 获取模板文件
+ Template t = ve.getTemplate("templates/interface.vm");
+ // 设置变量
+ VelocityContext ctx = new VelocityContext();
+ ctx.put("appName",projectInfo.getAppName());
+ ctx.put("moduleName", interfaceItem.getModuleName());
+ ctx.put("className",interfaceItem.getInterfaceName());
+ ctx.put("methodList",interfaceItem.getMethods());
+
+ // 输出
+ StringWriter sw = new StringWriter();
+ t.merge(ctx,sw);
+ FileWriter sourceFile = null;
+ try {
+ sourceFile = new FileWriter(this.projectSrcDir+ File.separator+interfaceItem.getModuleName()+".erl");
+ sourceFile.write(sw.toString());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }finally {
+ try {
+ sourceFile.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return true;
+ }
+
+ private boolean makeProjectDir(){
+ String savedir = System.getProperty("user.dir") + File.separator + "genProjectDir";
+ projectSaveDir=String.format("%s%s%s",savedir,File.separator,projectInfo.getAppName());
+
+ File rootDir = new File(projectSaveDir);
+ if(!rootDir.exists()){
+ if(!rootDir.mkdirs()){
+ return false;
+ }
+ }
+ projectSrcDir=String.format("%s%ssrc",projectSaveDir,File.separator);
+ File projectSrcFile= new File(projectSrcDir);
+ if(!projectSrcFile.exists()){
+ if(!projectSrcFile.mkdirs()){
+ return false;
+ }
+ }
+
+ projectIncludeDir=String.format("%s%sinclude",projectSaveDir,File.separator);
+ File projectIncludeFile= new File(projectIncludeDir);
+ if(!projectIncludeFile.exists()){
+ if(!projectIncludeFile.mkdirs()){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 生成项目公共文件
+ * @return
+ */
+ private boolean genProjectCommonFile(){
+ // 获取模板文件
+
+ VelocityContext ctx = new VelocityContext();
+ ctx.put("appName",projectInfo.getAppName());
+ ctx.put("appVersion",projectInfo.getAppVersion());
+
+
+ FileWriter appFile = null;
+ FileWriter appSrcFile = null;
+ FileWriter appSupFile = null;
+ try {
+ // 输出
+ Template appTpl = ve.getTemplate("templates/app.vm");
+ StringWriter appFileWriter = new StringWriter();
+ appTpl.merge(ctx,appFileWriter);
+
+ appFile = new FileWriter(this.projectSrcDir+ File.separator+projectInfo.getAppName()+"_app.erl");
+ appFile.write(appFileWriter.toString());
+
+ // 输出
+ Template appSrcTpl = ve.getTemplate("templates/app_src.vm");
+ StringWriter appSrcFileWriter = new StringWriter();
+ appSrcTpl.merge(ctx,appSrcFileWriter);
+ appSrcFile = new FileWriter(this.projectSrcDir+ File.separator+projectInfo.getAppName()+".app.src");
+ appSrcFile.write(appSrcFileWriter.toString());
+
+ Template appSupTpl = ve.getTemplate("templates/app_sup.vm");
+ StringWriter appSupFileWriter = new StringWriter();
+ appSupTpl.merge(ctx,appSupFileWriter);
+ appSupFile = new FileWriter(this.projectSrcDir+ File.separator+projectInfo.getAppName()+"_sup.erl");
+ appSupFile.write(appSupFileWriter.toString());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }finally {
+ try {
+ appFile.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ try {
+ appSrcFile.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ try {
+ appSupFile.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return true;
+ }
+
+ private void genProjectIncludeInfo(){
+ // 获取模板文件
+ Template t = ve.getTemplate("templates/app_type_include.vm");
+ // 设置变量
+ VelocityContext ctx = new VelocityContext();
+ ctx.put("typeList", CommonTypeInfo.getInstances().getCommonTypeList());
+ // 输出
+ StringWriter sw = new StringWriter();
+ t.merge(ctx,sw);
+ writeFile(this.projectIncludeDir+File.separator+projectInfo.getAppName()+".hrl",sw.toString());
+ }
+
+ private void genProjectTypeList(){
+ // 获取模板文件
+ Template t = ve.getTemplate("templates/app_type_list.vm");
+ // 设置变量
+ VelocityContext ctx = new VelocityContext();
+ ctx.put("appName",projectInfo.getAppName());
+ ctx.put("typeList", CommonTypeInfo.getInstances().getCommonTypeList());
+ // 输出
+ StringWriter sw = new StringWriter();
+ t.merge(ctx,sw);
+ writeFile(this.projectSrcDir+File.separator+projectInfo.getAppName()+"_type_list.erl",sw.toString());
+ }
+
+
+ private boolean writeFile(String filePath,String content){
+ FileWriter sourceFile = null;
+ try {
+ sourceFile = new FileWriter(filePath);
+ sourceFile.write(content);
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }finally {
+ try {
+ sourceFile.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/generater/ProjectInfo.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/generater/ProjectInfo.java
new file mode 100644
index 0000000..819aa9c
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/generater/ProjectInfo.java
@@ -0,0 +1,34 @@
+package org.apache.dubbo.erlang.analysis.generater;
+
+/**
+ * Created by dlive on 22/02/2018.
+ */
+public class ProjectInfo {
+ private String appName;
+ private String appVersion;
+ private String prefix;
+
+ public String getAppName() {
+ return appName.replace("-","_");
+ }
+
+ public void setAppName(String appName) {
+ this.appName = appName.replace("-","_");
+ }
+
+ public String getPrefix() {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public String getAppVersion() {
+ return appVersion;
+ }
+
+ public void setAppVersion(String appVersion) {
+ this.appVersion = appVersion;
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeFieldInfo.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeFieldInfo.java
new file mode 100644
index 0000000..041271a
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeFieldInfo.java
@@ -0,0 +1,31 @@
+package org.apache.dubbo.erlang.analysis.parse;
+
+import org.apache.dubbo.erlang.analysis.utils.ErlTypeTransformUtil;
+
+/**
+ * Created by dlive on 26/02/2018.
+ */
+public class CommonTypeFieldInfo {
+ private String fieldName;
+ private Class<?> fieldType;
+
+ public String getFieldName() {
+ return ErlTypeTransformUtil.stringFirstToLower(fieldName);
+ }
+
+ public void setFieldName(String fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ public Class<?> getFieldType() {
+ return fieldType;
+ }
+
+ public void setFieldType(Class<?> fieldType) {
+ this.fieldType = fieldType;
+ }
+
+ public String getFieldErlType(){
+ return ErlTypeTransformUtil.fullClassNameToErlType(fieldType.getName());
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeInfo.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeInfo.java
new file mode 100644
index 0000000..4cdf1b0
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeInfo.java
@@ -0,0 +1,109 @@
+package org.apache.dubbo.erlang.analysis.parse;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.util.*;
+
+import org.objectweb.asm.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class CommonTypeInfo {
+
+ private static CommonTypeInfo obj;
+ private final static Logger logger= LoggerFactory.getLogger(CommonTypeInfo.class);
+
+// private Set commonTypeList=new HashSet();
+ private Map<String,CommonTypeItem> commonTypeList= new HashMap<>();
+
+ public static CommonTypeInfo getInstances(){
+ if(obj==null){
+ obj=new CommonTypeInfo();
+ }
+ return obj;
+ }
+
+ public static void add(String commonArgType){
+ CommonTypeInfo typeinfo = getInstances();
+ typeinfo.parseTypeinfo(commonArgType);
+ }
+
+
+
+ private void addCommonTypeList(String typeName,CommonTypeItem item){
+
+ }
+
+ private void parseTypeinfo(String typeName){
+ if(commonTypeList.get(typeName)!=null){
+ return;
+ }
+ logger.info("will parse type info {}",typeName);
+ Type type = Type.getObjectType(typeName);
+ switch (type.getSort()){
+ case Type.ARRAY:
+ //todo
+ break;
+ case Type.OBJECT:
+ if(isTypeNeedParse(type.getClassName())){
+ parseTypeDetailInfo(type);
+ }else if(type.getClassName().startsWith("java.util.List")){
+
+ }
+ break;
+ default:
+ }
+ }
+
+ private void parseTypeDetailInfo(Type type){
+ CommonTypeItem typeItem = new CommonTypeItem();
+ typeItem.setClassName(type.getClassName());
+ Class classObj = null;
+ try {
+ classObj = Class.forName(type.getClassName(),false,Thread.currentThread().getContextClassLoader());
+ Field[] fields = classObj.getDeclaredFields();
+ for (Field field: fields) {
+ try {
+ PropertyDescriptor propertyDesc = new PropertyDescriptor(field.getName(),classObj);
+ if(propertyDesc.getReadMethod()==null && propertyDesc.getWriteMethod()==null){
+ continue;
+ }
+ } catch (IntrospectionException e) {
+ logger.warn("get field property error",e);
+ continue;
+ }
+ CommonTypeFieldInfo fieldInfo = new CommonTypeFieldInfo();
+ fieldInfo.setFieldName(field.getName());
+ fieldInfo.setFieldType(field.getType());
+ typeItem.addField(fieldInfo);
+ //判断该类型是否需要继续解析
+ parseTypeinfo(field.getType().getName());
+ }
+ commonTypeList.put(type.getClassName(),typeItem);
+ logger.debug("parse type detail success {}",type.getClassName());
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+
+
+ }
+
+ public List<CommonTypeItem> getCommonTypeList(){
+ List<CommonTypeItem> list=new ArrayList<>(commonTypeList.size());
+ for (Map.Entry<String, CommonTypeItem> item:commonTypeList.entrySet()){
+ CommonTypeItem type=item.getValue();
+ if(type.getTypeName().equals("list")){
+ continue;
+ }
+ list.add(item.getValue());
+ }
+ return list;
+ }
+ public boolean isTypeNeedParse(String typeName){
+ if(typeName.startsWith("java.lang")|| typeName.equals("int") || typeName.equals("double") || typeName.equals("float")){
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeItem.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeItem.java
new file mode 100644
index 0000000..cbe96e2
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/CommonTypeItem.java
@@ -0,0 +1,47 @@
+package org.apache.dubbo.erlang.analysis.parse;
+
+import org.apache.dubbo.erlang.analysis.utils.ErlTypeTransformUtil;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Created by dlive on 26/02/2018.
+ */
+public class CommonTypeItem {
+ private String className;
+ private Set fields=new HashSet();
+
+ public String getClassName() {
+ return className;
+ }
+
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ public Set getFields() {
+ return fields;
+ }
+
+ public void setFields(Set fields) {
+ this.fields = fields;
+ }
+ public void addField(CommonTypeFieldInfo field){
+ fields.add(field);
+ }
+
+ /**
+ * 获取类型名称
+ * @return
+ */
+ public String getTypeName(){
+ return ErlTypeTransformUtil.fullClassNameToLowerShortName(className);
+ }
+
+ public CommonTypeFieldInfo[] getFieldList(){
+ CommonTypeFieldInfo[] ret=new CommonTypeFieldInfo[fields.size()];
+ fields.toArray(ret);
+ return ret;
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/InterfaceInfo.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/InterfaceInfo.java
new file mode 100644
index 0000000..76d568d
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/InterfaceInfo.java
@@ -0,0 +1,36 @@
+package org.apache.dubbo.erlang.analysis.parse;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class InterfaceInfo {
+ private String interfaceName;
+ private List<MethodInfo> methods = new ArrayList<MethodInfo>();
+
+ public String getInterfaceName() {
+ return interfaceName;
+ }
+
+ public String getModuleName(){
+ String moduleName= interfaceName.substring(interfaceName.lastIndexOf(".")+1);
+ moduleName = moduleName.substring(0, 1).toLowerCase() + moduleName.substring(1);
+ moduleName = moduleName.replace('-','_');
+ return moduleName;
+ }
+
+ public void setInterfaceName(String interfaceName) {
+ this.interfaceName = interfaceName;
+ }
+
+
+ public List<MethodInfo> getMethods() {
+ return methods;
+ }
+
+ public void getMethodExportList(){
+
+ }
+ public void addMethods(MethodInfo method) {
+ this.methods.add(method);
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/InterfaceParse.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/InterfaceParse.java
new file mode 100644
index 0000000..136741c
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/InterfaceParse.java
@@ -0,0 +1,74 @@
+package org.apache.dubbo.erlang.analysis.parse;
+
+import org.apache.dubbo.erlang.analysis.generater.ErlProjectGenerater;
+import org.apache.dubbo.erlang.analysis.generater.ProjectInfo;
+import org.apache.dubbo.erlang.analysis.utils.MavenJarUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+
+public class InterfaceParse {
+ private final static Logger logger= LoggerFactory.getLogger(InterfaceParse.class);
+
+ public void parse(String group,String artifactid,String version){
+
+
+ MavenJarUtil mavenInfo = new MavenJarUtil(group, artifactid, version);
+ if(!mavenInfo.copyDependence()){
+ logger.error("download maven jar error");
+ }
+ String parserJarPath=mavenInfo.getMainJarPath();
+ logger.info("parse main jar "+ parserJarPath);
+ loadDependencyJar(mavenInfo.getRootDir()+File.separator+"lib");
+ ParseJarInterfaceInfo parser = new ParseJarInterfaceInfo();
+ List<InterfaceInfo> interfaceList = parser.parseJar(parserJarPath);
+
+ ProjectInfo projectInfo = new ProjectInfo();
+ projectInfo.setAppName(mavenInfo.getArtifactId());
+ projectInfo.setAppVersion(mavenInfo.getVersion());
+ projectInfo.setPrefix("test_");
+
+ ErlProjectGenerater generater = new ErlProjectGenerater(projectInfo);
+ generater.genProject(interfaceList);
+ }
+
+
+ private boolean loadDependencyJar(String rootPath){
+ File jarPathFile = new File(rootPath);
+ if(!jarPathFile.exists() || jarPathFile.isFile() ){
+ logger.error("load dependency error target dir unexist {}",rootPath);
+ return false;
+ }
+ List urlList=new ArrayList<URL>();
+ File[] fileList = jarPathFile.listFiles();
+ for(int i =0;i<fileList.length;i++){
+ File item = fileList[i];
+ if(item.isDirectory()){
+ continue;
+ }
+ try {
+ if(item.getAbsolutePath().endsWith(".jar")) {
+ urlList.add(item.toURI().toURL());
+ logger.debug("url class load add lib {}", item.getAbsolutePath());
+ }
+ } catch (MalformedURLException e) {
+ logger.error("get jar list error ",e);
+ }
+ }
+
+ URL[] urls = new URL[urlList.size()];
+ urlList.toArray(urls);
+ URLClassLoader cl = new URLClassLoader(urls,Thread.currentThread().getContextClassLoader());
+ Thread.currentThread().setContextClassLoader(cl);
+ return true;
+ }
+
+
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/MethodInfo.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/MethodInfo.java
new file mode 100644
index 0000000..1979cc8
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/MethodInfo.java
@@ -0,0 +1,104 @@
+package org.apache.dubbo.erlang.analysis.parse;
+
+
+import org.apache.dubbo.erlang.analysis.utils.ErlTypeTransformUtil;
+import org.objectweb.asm.Type;
+
+import java.util.*;
+
+public class MethodInfo {
+ private String name;
+
+ private String methodDescriptor;
+ private String argsType;
+ private int argsLength;
+ private String returnType;
+ private String[] parameterName;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getArgsType() {
+ return argsType;
+ }
+
+ public void setArgsType(String argsType) {
+ this.argsType = argsType;
+ }
+
+ public String getReturnType() {
+ return returnType;
+ }
+
+ public void setReturnType(String returnType) {
+ this.returnType = returnType;
+ }
+
+
+ public String getParameterNameString(){
+ return String.join(",",parameterName);
+ }
+
+ public void setParameterName(String[] parameterName) {
+ for(int i=0;i<parameterName.length;i++){
+ parameterName[i] = parameterName[i].substring(0, 1).toUpperCase() + parameterName[i].substring(1);
+ }
+ this.parameterName = parameterName;
+ }
+
+ public String getParameterTypeDef(){
+ ArrayList<String> retList = new ArrayList<>();
+ Type[] types = Type.getArgumentTypes(methodDescriptor);
+ for(int i=0;i<types.length;i++){
+ String def= ErlTypeTransformUtil.fullClassNameToTypeDef(types[i].getClassName());
+ retList.add(def);
+ }
+ return String.join(",\n",retList);
+ }
+
+ public Map<String,String> getParameterTypeList(){
+ Type[] types = Type.getArgumentTypes(methodDescriptor);
+ Map<String,String> retInfo = new LinkedHashMap<>();
+ for(int i=0;i<types.length;i++){
+ String def=ErlTypeTransformUtil.fullClassNameToErlType(types[i].getClassName());
+ retInfo.put(parameterName[i],def);
+ }
+ return retInfo;
+ }
+
+ /**
+ * get -spec return type
+ * @return
+ */
+ public String getReturnErlType(){
+ Type types = Type.getReturnType(methodDescriptor);
+ return ErlTypeTransformUtil.fullClassNameToErlType(types.getClassName());
+ }
+
+ public String getResponseTypeDef(){
+ Type types = Type.getReturnType(methodDescriptor);
+ return ErlTypeTransformUtil.fullClassNameToTypeDef(types.getClassName());
+ }
+
+ public String getMethodDescriptor() {
+ return methodDescriptor;
+ }
+
+ public void setMethodDescriptor(String methodDescriptor) {
+ this.methodDescriptor = methodDescriptor;
+ }
+
+
+ public int getArgsLength() {
+ return argsLength;
+ }
+
+ public void setArgsLength(int argsLength) {
+ this.argsLength = argsLength;
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/ParseJarInterfaceInfo.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/ParseJarInterfaceInfo.java
new file mode 100644
index 0000000..1985c67
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/parse/ParseJarInterfaceInfo.java
@@ -0,0 +1,196 @@
+package org.apache.dubbo.erlang.analysis.parse;
+
+import org.objectweb.asm.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.*;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+
+public class ParseJarInterfaceInfo {
+ private final static Logger logger= LoggerFactory.getLogger(ParseJarInterfaceInfo.class);
+
+ static final String CLAZZ = ".class";
+
+
+ public List<InterfaceInfo> parseJar(String jarfile) {
+ List<InterfaceInfo> list_interfaces = getInterfaceList(jarfile);
+ JarFile jarFile = null;
+ InputStream inputInteface = null;
+ try {
+ jarFile = new JarFile(jarfile);
+ String interfacePathName;
+ for (InterfaceInfo interfaceItem : list_interfaces) {
+
+ }
+ } catch (IOException e) {
+ logger.debug("parse:",e);
+ }finally {
+ if(jarFile!=null) {
+ try {
+ jarFile.close();
+ } catch (IOException e) {
+ logger.error("",e);
+ }
+ }
+ if(inputInteface!=null)
+ try {
+ inputInteface.close();
+ } catch (IOException e) {
+ logger.error("",e);
+ }
+ }
+// parseArgs(jarfile);
+ return list_interfaces;
+ }
+
+ private List<InterfaceInfo> getInterfaceList(String jarfilePath) {
+ JarInputStream jarFile = null;
+ JarEntry jarEntry;
+ String name;
+ List<InterfaceInfo> list_interfaces = new ArrayList<InterfaceInfo>();
+ try {
+ jarFile = new JarInputStream(new FileInputStream(jarfilePath));
+ jarEntry = jarFile.getNextJarEntry();
+ while (jarEntry != null) {
+ name = jarEntry.getName();
+ if (name.endsWith(CLAZZ)) {
+ logger.debug(name);
+ if(name.indexOf("WEB-INF/classes/")>-1)
+ name = name.substring(16,name.length());
+ name = name.replace("/",".").substring(0,name.length()-6);
+ logger.debug("get interfaceName {}",name);
+ Class tmpClass = Class.forName(name,false,Thread.currentThread().getContextClassLoader());
+ if(tmpClass.isInterface()){
+ InterfaceInfo newInterface = new InterfaceInfo();
+ newInterface.setInterfaceName(name);
+ parseClassMethods(tmpClass,newInterface);
+ list_interfaces.add(newInterface);
+ }
+ }
+ jarEntry = jarFile.getNextJarEntry();
+ }
+ } catch (IOException e) {
+ logger.error("",e);
+ }catch (Exception e){
+ logger.error("",e);
+ }finally {
+ if (jarFile != null) {
+ try {
+ jarFile.close();
+ } catch (IOException e) {
+ logger.error("",e);
+ }
+ }
+ }
+ return list_interfaces;
+ }
+
+ private void parseClassMethods(Class classObj,InterfaceInfo interfaceInfo){
+ Method[] methodsList = classObj.getDeclaredMethods();
+ for(int i=0;i<methodsList.length;i++){
+ Method method = methodsList[i];
+ MethodInfo methodInfo = new MethodInfo();
+ methodInfo.setName(method.getName());
+ String methodDescriptor = Type.getMethodDescriptor(method);
+ methodInfo.setMethodDescriptor(methodDescriptor);
+
+ int tmpIndex = methodDescriptor.indexOf(")");
+ String argsDescriptor=methodDescriptor.substring(1,tmpIndex);
+ String returnDescriptor=methodDescriptor.substring(tmpIndex);
+ methodInfo.setArgsType(argsDescriptor);
+ methodInfo.setReturnType(returnDescriptor);
+
+ methodInfo.setArgsLength(Type.getArgumentTypes(method).length);
+
+ Parameter[] parameters = method.getParameters();
+ String[] paramterNames=new String[parameters.length];
+ for(int index=0;index < parameters.length;index++){
+ paramterNames[index]=parameters[index].getName();
+ }
+ methodInfo.setParameterName(paramterNames);
+// 通过asm获取存在为null的情况。
+// try {
+// String[] paramterNames = MethodParseUtil.getMethodParamNames(method);
+// methodInfo.setParameterName(paramterNames);
+// } catch (IOException e) {
+// logger.warn("无法获取参数名称",e);
+// Parameter[] parameters = method.getParameters();
+// String[] paramterNames=new String[parameters.length];
+// for(int index=0;index<parameters.length;index++){
+// paramterNames[i]=parameters[i].getName();
+// }
+// methodInfo.setParameterName(paramterNames);
+// }
+
+
+ interfaceInfo.addMethods(methodInfo);
+
+ checkCommonType(Type.getArgumentTypes(method));
+ checkCommonType(Type.getReturnType(method));
+ }
+ }
+ private void checkCommonType(Type[] types){
+ for(int i=0;i<types.length;i++){
+ checkCommonType(types[i]);
+ }
+ }
+ private void checkCommonType(Type type){
+ CommonTypeInfo.add(type.getClassName());
+
+// switch (type.getSort()){
+// case Type.ARRAY:
+//
+// break;
+// case Type.OBJECT:
+// type.getClassName();
+// if(!type.getClassName().startsWith("java.lang")){
+// CommonTypeInfo.add(type.getClassName());
+// }
+// break;
+// default:
+// }
+ }
+
+// private String[] generalMethodId(Method method, ClassUtils utils, String classPath){
+// String[] pathOfMethods = utils.getPathOfMethod(method);
+// String requestType = utils.getRequestType(method);
+// List<String> annotationParameters = utils.getAnnotationParameters(method,false);
+// String[] methodIds = new String[pathOfMethods.length];
+// int count = 0;
+// for(String pathOfMethod:pathOfMethods){
+// String urlPath = utils.getUrlPath(annotationParameters, classPath, pathOfMethod);
+// if(urlPath.indexOf("/{")>0)
+// urlPath = urlPath.replace("/{","/${");
+// if(urlPath.indexOf("={")>0)
+// urlPath = urlPath.replace("={","=${");
+// String methodId = requestType+"#"+urlPath;
+// methodIds[count++]=methodId;
+// }
+//
+// return methodIds;
+// }
+
+ private String formatData(List<String> list,String prefix,String suffix,boolean isJsonFormat){
+ StringBuilder jsonSb = new StringBuilder(prefix);
+ for(String key : list){
+ if(jsonSb.length()>1)
+ jsonSb.append(",");
+ if(isJsonFormat)
+ jsonSb.append("\""+key+"\":"+",\"\"") ;
+ else
+ jsonSb.append(key);
+ }
+ jsonSb.append(suffix);
+ if(jsonSb.length()<2)
+ jsonSb.delete(0,jsonSb.length());
+ return jsonSb.toString();
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/ErlTypeTransformUtil.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/ErlTypeTransformUtil.java
new file mode 100644
index 0000000..163ee8c
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/ErlTypeTransformUtil.java
@@ -0,0 +1,85 @@
+package org.apache.dubbo.erlang.analysis.utils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Created by dlive on 23/02/2018.
+ */
+public class ErlTypeTransformUtil {
+
+ public static String fullClassNameToTypeDef(String fullClassName){
+ String className = fullClassName.substring(fullClassName.lastIndexOf(".")+1);
+ className = className.substring(0, 1).toLowerCase() + className.substring(1);
+ String fieldNames = "";
+ switch (className){
+ case "string":
+ fieldNames="[]";
+ break;
+ default:
+ fieldNames = String.format("record_info(fields,%s)",className);
+ }
+ return String.format("#type_def{foreign_type = <<\"%s\">>,\n" +
+ " native_type = %s,\n" +
+ " fieldnames = %s}",fullClassName,className,fieldNames);
+ }
+
+ public static String fullClassNameToLowerShortName(String fullClassName){
+ String className = fullClassName.substring(fullClassName.lastIndexOf(".")+1);
+ className = className.substring(0, 1).toLowerCase() + className.substring(1);
+ return className;
+ }
+
+ public static String stringFirstToLower(String str){
+ str = str.substring(0, 1).toLowerCase() + str.substring(1);
+ return str;
+ }
+
+ public static String fullClassNameToErlType(String fullClassName){
+ try {
+ String type=null;
+ if(fullClassName.startsWith("java.lang")|| fullClassName.equals("int") || fullClassName.equals("double") || fullClassName.equals("float")){
+ switch (fullClassName){
+ case "java.lang.String":
+ type="list()";
+ break;
+ case "java.lang.Integer":
+ type="integer()";
+ break;
+ case "java.lang.Boolean":
+ type="boolean()";
+ break;
+ case "java.lang.Float":
+ type="float()";
+ break;
+ case "int":
+ type="integer()";
+ break;
+ case "double":
+ type="float()";
+ break;
+ default:
+ return "unkonw";
+ }
+
+ return type;
+ }
+ Class<?> classInfo = Class.forName(fullClassName, false, Thread.currentThread().getContextClassLoader());
+
+ if(classInfo.isAssignableFrom(List.class) ){
+ type="[]";
+ }else if(classInfo.isAssignableFrom(Map.class) ){
+ type="Map";
+ }else if(classInfo.isAssignableFrom(Set.class) ){
+ type="Set";
+ }else{
+ type = "#"+fullClassNameToLowerShortName(fullClassName)+"{}";
+ }
+ return type;
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/MavenJarUtil.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/MavenJarUtil.java
new file mode 100644
index 0000000..1269955
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/MavenJarUtil.java
@@ -0,0 +1,178 @@
+package org.apache.dubbo.erlang.analysis.utils;
+
+
+import org.apache.maven.shared.invoker.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+
+/**
+ * Created by dlive on 16/5/31.
+ */
+public class MavenJarUtil {
+ private String groupid;
+ private String artifactId;
+ private String version;
+ private String mainJarPath;
+ private String rootDir;
+ private static Logger log = LoggerFactory.getLogger(MavenJarUtil.class);
+
+ public MavenJarUtil(String groupid, String artifactId, String version){
+ this.groupid = groupid;
+ this.artifactId = artifactId;
+ this.version = version;
+
+
+ }
+
+ public boolean copyDependence(){
+ String mvn_home = System.getenv("MAVEN_HOME");
+ this.rootDir = genProjectDir(System.getProperty("project_save_dir",System.getProperty("user.dir")+File.separator+"mavenDown"));
+ if(rootDir==null){
+ return false;
+ }
+
+ log.info("down load lib jar dir:"+rootDir);
+ String pomPathJar = genPomFile(this.rootDir,"jar");
+
+ InvocationRequest request = new DefaultInvocationRequest();
+ request.setPomFile( new File( pomPathJar ) );
+ request.setGoals( Collections.singletonList( "compile" ) );
+
+ Invoker invoker = new DefaultInvoker();
+ try {
+ if(mvn_home!=null){
+ log.info("use MAVEN_HOME:"+mvn_home);
+ invoker.setMavenHome(new File(mvn_home));
+ }
+
+ invoker.setWorkingDirectory(new File(rootDir));
+ InvocationResult result = invoker.execute( request );
+ if(result.getExitCode()!=0){
+ String pomPathWar = genPomFile(this.rootDir,"war");
+ InvocationRequest requestWar = new DefaultInvocationRequest();
+ requestWar.setPomFile(new File(pomPathWar));
+ requestWar.setGoals(Collections.singletonList("compile"));
+ invoker.setWorkingDirectory(new File(rootDir));
+ InvocationResult resultWar = invoker.execute( requestWar );
+ if(resultWar.getExitCode()!=0){
+ log.error("mvn run result exception:"+resultWar.getExecutionException());
+ return false;
+ }
+ }
+
+ } catch (MavenInvocationException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ private String genPomFile(String rootDir,String pomDependenType ){
+
+ String pomContent = String.format("<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n" +
+ " <modelVersion>4.0.0</modelVersion>\n" +
+ " <groupId>net.ifcoder.erlanalysis</groupId>\n" +
+ " <artifactId>denpendencedown</artifactId>\n" +
+ " <packaging>pom</packaging>\n" +
+ " <version>1.0-SNAPSHOT</version>\n" +
+ " <name>denpendencedown</name>\n" +
+ " <url>http://maven.apache.org</url>\n" +
+ " <dependencies>\n" +
+ "\t <dependency>\n" +
+ "\t\t <groupId>%s</groupId>\n" +
+ "\t\t <artifactId>%s</artifactId>\n" +
+ "\t\t <version>%s</version><type>%s</type>\n" +
+ " <exclusions>\n" +
+ " <exclusion>\n" +
+ " <groupId>log4j</groupId>\n" +
+ " <artifactId>log4j</artifactId>\n" +
+ " </exclusion>\n" +
+ " </exclusions>"+
+ "\t </dependency>\n" +
+ " </dependencies>\n" +
+ " <build>\n" +
+ " <plugins>\n" +
+ " <plugin>\n" +
+ " <groupId>org.apache.maven.plugins</groupId>\n" +
+ " <artifactId>maven-dependency-plugin</artifactId>\n" +
+ " <version>2.10</version>\n" +
+ "<executions>\n" +
+ " <execution>\n" +
+ " <id>copy-dependencies</id>\n" +
+ " <phase>compile</phase>\n" +
+ " <goals>\n" +
+ " <goal>copy-dependencies</goal>\n" +
+ " </goals>\n" +
+ " <!-- <configuration>\n" +
+ " <outputDirectory>${basedir}/lib</outputDirectory>\n" +
+ " <excludeScope>provided</excludeScope>\n" +
+ " </configuration> -->\n" +
+ " </execution>\n" +
+ " </executions>"+
+ " <configuration>\n" +
+ "\t\t\t\t\t <outputDirectory>${basedir}/lib</outputDirectory>\n" +
+ "\t\t\t\t\t <excludeScope>provided</excludeScope>\n" +
+ " <excludeArtifactIds>commons-logging</excludeArtifactIds>\n" +
+ " </configuration>"+
+ " </plugin>\n" +
+ " </plugins>\n" +
+ " </build>\n" +
+ "</project>\n",groupid,artifactId,version,pomDependenType);
+ //logback-core,logback-classic,
+ String pompath = rootDir+File.separator+"pom.xml";
+ log.info("will create pom file:"+pompath);
+ File pomfile = new File(pompath);
+ try {
+ //pomfile.createNewFile();
+ FileOutputStream out=new FileOutputStream(pomfile);
+ out.write(pomContent.getBytes());
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ }
+ return pompath;
+ }
+
+ private String genProjectDir(String savedir){
+
+
+ String tmpSavePath;
+ if(savedir.endsWith(File.separator)){
+ tmpSavePath=String.format("%s%s%s%s",savedir,this.artifactId,File.separator,this.version);
+ }else{
+ tmpSavePath=String.format("%s%s%s%s%s",savedir,File.separator,this.artifactId,File.separator,this.version);
+ }
+ File rootDir = new File(tmpSavePath);
+ if(!rootDir.exists()){
+ if(!rootDir.mkdirs()){
+ return null;
+ }
+ }
+ return tmpSavePath;
+ }
+
+ public String getMainJarPath() {
+ if(mainJarPath==null){
+ mainJarPath=String.format("%s%slib%s%s-%s.jar",rootDir,File.separator,File.separator,artifactId,version);
+ }
+ return mainJarPath;
+ }
+
+ public String getRootDir() {
+ return rootDir;
+ }
+
+ public String getArtifactId(){
+ return artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+}
diff --git a/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/MethodParseUtil.java b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/MethodParseUtil.java
new file mode 100644
index 0000000..04b3b25
--- /dev/null
+++ b/tools/erlanalysis/src/main/java/org/apache/dubbo/erlang/analysis/utils/MethodParseUtil.java
@@ -0,0 +1,63 @@
+package org.apache.dubbo.erlang.analysis.utils;
+
+import org.objectweb.asm.*;
+
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * Created by dlive on 23/02/2018.
+ */
+public class MethodParseUtil {
+ public static String[] getMethodParamNames(final Method method) throws IOException {
+
+ final String methodName = method.getName();
+ final Class<?>[] methodParameterTypes = method.getParameterTypes();
+ final int methodParameterCount = methodParameterTypes.length;
+ final String className = method.getDeclaringClass().getName();
+ final boolean isStatic = Modifier.isStatic(method.getModifiers());
+ final String[] methodParametersNames = new String[methodParameterCount];
+
+ ClassReader cr = new ClassReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(className.replace('.', '/') + ".class"));
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+ cr.accept(new ClassVisitor(Opcodes.ASM5,cw) {
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+
+ MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+
+ final Type[] argTypes = Type.getArgumentTypes(desc);
+
+ //参数类型不一致
+ if (!methodName.equals(name) || !matchTypes(argTypes, methodParameterTypes)) {
+ return mv;
+ }
+
+ return new MethodVisitor(Opcodes.ASM5,mv) {
+ public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
+ //如果是静态方法,第一个参数就是方法参数,非静态方法,则第一个参数是 this ,然后才是方法的参数
+ int methodParameterIndex = isStatic ? index : index - 1;
+ if (0 <= methodParameterIndex && methodParameterIndex < methodParameterCount) {
+ methodParametersNames[methodParameterIndex] = name;
+ }
+ super.visitLocalVariable(name, desc, signature, start, end, index);
+ }
+ };
+ }
+ }, 0);
+ return methodParametersNames;
+ }
+
+ private static boolean matchTypes(Type[] types, Class<?>[] parameterTypes) {
+ if (types.length != parameterTypes.length) {
+ return false;
+ }
+ for (int i = 0; i < types.length; i++) {
+ if (!Type.getType(parameterTypes[i]).equals(types[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/tools/erlanalysis/src/main/resources/log4j.properties b/tools/erlanalysis/src/main/resources/log4j.properties
new file mode 100644
index 0000000..d6e4cfe
--- /dev/null
+++ b/tools/erlanalysis/src/main/resources/log4j.properties
@@ -0,0 +1,8 @@
+log4j.rootLogger=DEBUG,console
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=DEBUG
+#log4j.appender.console.ImmediateFlush=true
+#log4j.appender.console.Target=System.err
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [%c]-[%p] %m%n
diff --git a/tools/erlanalysis/src/main/resources/templates/app.vm b/tools/erlanalysis/src/main/resources/templates/app.vm
new file mode 100644
index 0000000..f0a6267
--- /dev/null
+++ b/tools/erlanalysis/src/main/resources/templates/app.vm
@@ -0,0 +1,39 @@
+%%%-------------------------------------------------------------------
+%% @doc ${appName} public API
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(${appName}_app).
+
+-behaviour(application).
+
+%% Application callbacks
+-export([start/2, stop/1]).
+
+-include("${appName}.hrl").
+
+
+%%====================================================================
+%% API
+%%====================================================================
+
+start(_StartType, _StartArgs) ->
+ register_type_list(),
+ ${appName}_sup:start_link().
+
+%%--------------------------------------------------------------------
+stop(_State) ->
+ ok.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
+
+
+register_type_list()->
+ List = ${appName}_type_list:get_list(),
+ lists:map(
+ fun({NativeType,ForeignType,Fields}) ->
+ dubbo_type_transfer:pre_process_typedef(NativeType,ForeignType,Fields)
+ end,List),
+ ok.
\ No newline at end of file
diff --git a/tools/erlanalysis/src/main/resources/templates/app_src.vm b/tools/erlanalysis/src/main/resources/templates/app_src.vm
new file mode 100644
index 0000000..e58040e
--- /dev/null
+++ b/tools/erlanalysis/src/main/resources/templates/app_src.vm
@@ -0,0 +1,17 @@
+{application, ${appName},
+[
+ {description, "An OTP application"},
+ {vsn, "${appVersion}"},
+ {registered, []},
+ {mod, { ${appName}_app, []}},
+ {applications,
+ [kernel,
+ stdlib,
+ dubboerl
+ ]},
+ {env,[]},
+ {modules, []},
+ {maintainers, []},
+ {licenses, []},
+ {links, []}
+]}.
diff --git a/tools/erlanalysis/src/main/resources/templates/app_sup.vm b/tools/erlanalysis/src/main/resources/templates/app_sup.vm
new file mode 100644
index 0000000..ef7ad74
--- /dev/null
+++ b/tools/erlanalysis/src/main/resources/templates/app_sup.vm
@@ -0,0 +1,35 @@
+%%%-------------------------------------------------------------------
+%% @doc ${appName} top level supervisor.
+%% @end
+%%%-------------------------------------------------------------------
+
+-module(${appName}_sup).
+
+-behaviour(supervisor).
+
+%% API
+-export([start_link/0]).
+
+%% Supervisor callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+%%====================================================================
+%% API functions
+%%====================================================================
+
+start_link() ->
+ supervisor:start_link({local, ?SERVER}, ?MODULE, []).
+
+%%====================================================================
+%% Supervisor callbacks
+%%====================================================================
+
+%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
+init([]) ->
+ {ok, { {one_for_all, 0, 1}, []} }.
+
+%%====================================================================
+%% Internal functions
+%%====================================================================
diff --git a/tools/erlanalysis/src/main/resources/templates/app_type_include.vm b/tools/erlanalysis/src/main/resources/templates/app_type_include.vm
new file mode 100644
index 0000000..c664968
--- /dev/null
+++ b/tools/erlanalysis/src/main/resources/templates/app_type_include.vm
@@ -0,0 +1,10 @@
+
+#foreach($typeItem in $typeList)
+-record(${typeItem.getTypeName()},{
+#foreach($fieldItem in ${typeItem.getFieldList()})
+ ${fieldItem.getFieldName()} ::${fieldItem.getFieldErlType()}#if($foreach.hasNext),
+#end
+#end
+}).
+
+#end
\ No newline at end of file
diff --git a/tools/erlanalysis/src/main/resources/templates/app_type_list.vm b/tools/erlanalysis/src/main/resources/templates/app_type_list.vm
new file mode 100644
index 0000000..f8badd1
--- /dev/null
+++ b/tools/erlanalysis/src/main/resources/templates/app_type_list.vm
@@ -0,0 +1,17 @@
+-module(${appName}_type_list).
+
+%% API
+-export([register_type_list/0,get_list/0]).
+
+-include("${appName}.hrl").
+
+get_list()->
+ [
+#foreach($typeItem in $typeList)
+ {${typeItem.getTypeName()},<<"${typeItem.getClassName()}">>,record_info(fields,${typeItem.getTypeName()})}#if($foreach.hasNext),
+#end
+#end
+ ].
+
+register_type_list()->
+ ok.
\ No newline at end of file
diff --git a/tools/erlanalysis/src/main/resources/templates/interface.vm b/tools/erlanalysis/src/main/resources/templates/interface.vm
new file mode 100644
index 0000000..5fc734d
--- /dev/null
+++ b/tools/erlanalysis/src/main/resources/templates/interface.vm
@@ -0,0 +1,83 @@
+-module(${moduleName}).
+
+-include_lib("dubboerl/include/dubbo.hrl").
+-include_lib("dubboerl/include/hessian.hrl").
+
+-define(CURRENT_CLASS_NAME,<<"${className}"/utf8>>).
+-define(CURRENT_CLASS_VERSION,<<"0.0.0"/utf8>>).
+
+-include("${appName}.hrl").
+
+
+
+
+%% API
+-export([
+#foreach($methodItem in $methodList)
+ #set($argsLength=${methodItem.getArgsLength()} + 1 )
+ ${methodItem.getName()}/${methodItem.getArgsLength()},
+ ${methodItem.getName()}/${argsLength}#if($foreach.hasNext),
+#end
+#end
+]).
+
+-export([get_method_999_list/0]).
+
+%% behaviour
+#foreach($methodItem in $methodList)
+-callback ${methodItem.getName()}(##
+#foreach($argsItemEntry in $methodItem.getParameterTypeList().entrySet())##
+${argsItemEntry.key}::${argsItemEntry.value}#if($foreach.hasNext),
+ #end##
+#end)-> ${methodItem.getReturnErlType()}.
+#end
+
+get_method_999_list()->
+ [
+#foreach($methodItem in $methodList)
+ ${methodItem.getName()}#if($foreach.hasNext),
+#end
+#end].
+
+
+#foreach($methodItem in $methodList)
+#*
+方法申明
+ *#
+-spec ${methodItem.getName()}(##
+#foreach($argsItemEntry in $methodItem.getParameterTypeList().entrySet())
+${argsItemEntry.key}::${argsItemEntry.value}#if($foreach.hasNext),##
+#end
+#end)->
+ {ok,reference()}|
+ {ok,reference(),Data::${methodItem.getReturnErlType()},RpcContent::list()}|
+ {error,Reason::timeout|no_provider|any()}.
+${methodItem.getName()}(${methodItem.getParameterNameString()})->
+ ${methodItem.getName()}(${methodItem.getParameterNameString()} #if($methodItem.getParameterNameString().length()>0),#end#{}).
+
+${methodItem.getName()}(${methodItem.getParameterNameString()}#if($methodItem.getParameterNameString().length()>0),#end RequestOption)->
+ #*
+ ResponseTypeList=[
+ ${methodItem.getResponseTypeDef()}
+ ],
+ *#
+ Data = #dubbo_rpc_invocation{
+ className = ?CURRENT_CLASS_NAME,
+ classVersion = ?CURRENT_CLASS_VERSION,
+ methodName = <<"${methodItem.getName()}">>,
+ parameterDesc = <<"${methodItem.getArgsType()}"/utf8>>,
+ parameterTypes = [
+ ${methodItem.getParameterTypeDef()}
+ ],
+ parameters = [
+ ${methodItem.getParameterNameString()}
+ ],
+ attachments = [
+ {<<"path">>, ?CURRENT_CLASS_NAME},
+ {<<"interface">> , ?CURRENT_CLASS_NAME}
+ ]
+ },
+ Request = dubbo_adapter:reference(Data),
+ dubbo_invoker:invoke_request(?CURRENT_CLASS_NAME,Request,RequestOption).
+
+#end
\ No newline at end of file
diff --git a/tools/erlanalysis/src/test/java/org/apache/dubbo/erlang/analysis/parse/InterfaceParseTest.java b/tools/erlanalysis/src/test/java/org/apache/dubbo/erlang/analysis/parse/InterfaceParseTest.java
new file mode 100644
index 0000000..4b57303
--- /dev/null
+++ b/tools/erlanalysis/src/test/java/org/apache/dubbo/erlang/analysis/parse/InterfaceParseTest.java
@@ -0,0 +1,10 @@
+package org.apache.dubbo.erlang.analysis.parse;
+
+import junit.framework.TestCase;
+
+public class InterfaceParseTest extends TestCase {
+ public void testParse() throws Exception {
+ InterfaceParse parser = new InterfaceParse();
+ parser.parse("org.apache.dubbo.erlang","dubbo-sample-service","1.3");
+ }
+}
\ No newline at end of file