diff --git a/apm-protocol/apm-ui-query/pom.xml b/apm-protocol/apm-ui-protocol/pom.xml
similarity index 82%
rename from apm-protocol/apm-ui-query/pom.xml
rename to apm-protocol/apm-ui-protocol/pom.xml
index f67c5c86e..0e7e75784 100644
--- a/apm-protocol/apm-ui-query/pom.xml
+++ b/apm-protocol/apm-ui-protocol/pom.xml
@@ -27,7 +27,13 @@
4.0.0
- apm-ui-query
+ apm-ui-protocol
-
-
\ No newline at end of file
+
+
+ com.graphql-java
+ graphql-java
+ 6.0
+
+
+
diff --git a/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/README.md b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/README.md
new file mode 100644
index 000000000..60ddb04aa
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/README.md
@@ -0,0 +1,41 @@
+# Abstract
+**apm-ui-protocol** declares all services, using GraphQL API style, which provide by Collector UI module.
+
+## Services
+### [Common](common.graphqls)
+
+Include common objects, which used in global
+
+### [Overview Layer Service](overview-layer.graphqls)
+
+Query data without specific application, server or service. It includes info for overview the whole cluster.
+
+### [Application Layer Service](application-layer.graphqls)
+
+Query application related data with specific application code.
+
+### [Server Layer Service](server-layer.graphqls)
+
+Query server related data with specific server id.
+
+### [Service Layer Service](service-layer.graphqls)
+
+Query service related data with specific service id
+
+### [Trace Service](trace.graphqls)
+
+Query trace by some conditions.
+
+### [Alarm Service](alarm.graphqls)
+
+Query alarm info.
+
+## Version
+v1alpha1
+
+### Versioning
+Use URI Versioning, to follow the most straightforward approach,
+though it does violate the principle that a URI should refer to a unique resource.
+
+e.g.
+http://collector.host/graphql/v1alpha1
diff --git a/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/alarm.graphqls b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/alarm.graphqls
new file mode 100644
index 000000000..b63946d8b
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/alarm.graphqls
@@ -0,0 +1,15 @@
+type AlarmItem {
+ content: String!
+ startTime: String!
+ alertType: AlarmType!
+}
+
+enum AlarmType {
+ APPLICATION,
+ SERVER,
+ SERVICE
+}
+
+extend type Query {
+ loadAlertList(keyword: String, alertType: AlarmType, duration:Duration!):[AlarmItem]
+}
\ No newline at end of file
diff --git a/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/application-layer.graphqls b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/application-layer.graphqls
new file mode 100644
index 000000000..ef9fc7007
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/application-layer.graphqls
@@ -0,0 +1,37 @@
+# ApplicationNode represents this node is under monitoring by agent.
+type ApplicationNode implements Node {
+ id: ID!
+ name: String!
+ type: String
+ # Success rate of all incoming requests.
+ # Max value is 100.
+ # 2 Digits after floating point.
+ sla: Float!
+ # The number of incoming calls
+ calls: Long!
+ # ref: http://www.apdex.org/
+ # Max value is 1
+ # 2 Digits after floating point.
+ apdex: Float!
+ # The number of servers in the application code
+ numOfServer: Int!
+ # The number of servers alerting
+ numOfServerAlarm: Int!
+ # The number of services alerting
+ numOfServiceAlarm: Int!
+}
+
+# The conjectural node generated by exit span
+type ConjecturalNode implements Node {
+ id: ID!
+ name: String!
+ type: String
+}
+
+
+extend type Query {
+ getAllApplication(duration: Duration!): [ApplicationNode]
+ getApplicationTopology(applicationId: ID!, duration: Duration!): Topology
+ getSlowService(applicationId: ID!, duration: Duration!): [ServiceInfo!]
+ getServerThroughput(applicationId: ID!, duration: Duration!): [AppServerInfo!]
+}
diff --git a/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/common.graphqls b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/common.graphqls
new file mode 100644
index 000000000..853f36258
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/common.graphqls
@@ -0,0 +1,88 @@
+schema {
+ query: Query
+}
+
+#Root node
+type Query {
+ version: String
+}
+
+# The Duration defines the start and end time for each query operation.
+# Fields: `start` and `end`
+# represents the time span. And each of them matches the step.
+# ref https://www.ietf.org/rfc/rfc3339.txt
+# The time formats are
+# `SECOND` step: yyyy-MM-dd HHmmss
+# `MINUTE` step: yyyy-MM-dd HHmm
+# `HOUR` step: yyyy-MM-dd HH
+# `DAY` step: yyyy-MM-dd
+# `MONTH` step: yyyy-MM
+# Field: `step`
+# represents the accurate time point.
+# e.g.
+# if step==HOUR , start=2017-11-08 09, end=2017-11-08 19
+# then
+# metrics from the following time points expected
+# 2017-11-08 9:00 -> 2017-11-08 19:00
+# there are 11 time points (hours) in the time span.
+input Duration {
+ start: String!
+ end: String!
+ step: Step!
+}
+
+enum Step {
+ MONTH
+ DAY
+ HOUR
+ MINUTE
+ SECOND
+}
+
+######################################
+# Common Metrics and Trends
+######################################
+type ResponseTimeTrend {
+ trendList: [Int!]
+}
+
+type ThroughputTrend {
+ trendList: [Int!]
+}
+
+type SLATrend {
+ trendList: [Int!]
+}
+
+# The overview topology of the whole application cluster or services,
+type Topology {
+ nodes: [Node]!
+ calls: [Call]
+}
+
+# The base Node of all node types in topology
+interface Node {
+ # The global id of each node,
+ # 1. `Application ID` represents application under monitoring
+ # 2. `Peer ID` string represents the conjectural dependency.
+ id: ID!
+ # Application Code or literal Peer
+ name: String!
+ # The type name
+ # 1. The most important component in the application, from service provider perspective.
+ # 2. Conjectural dependent component, e.g. MySQL, Redis, Kafka
+ type: String
+}
+
+# The Call represents a directed distributed call,
+# from the `source` to the `target`.
+type Call {
+ source: ID!
+ target: ID!
+ isAlert: Boolean
+ # The protocol and tech stack used in this distributed call
+ callType: String!
+ callsPerSec: Int!
+ # Unit: millisecond
+ responseTimePerSec: Int!
+}
diff --git a/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/overview-layer.graphqls b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/overview-layer.graphqls
new file mode 100644
index 000000000..e7b0bc2d6
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/overview-layer.graphqls
@@ -0,0 +1,37 @@
+# Query the cluster brief based on the given duration
+type ClusterBrief {
+ numOfApplication: Int
+ numOfService: Int
+ numOfDatabase: Int
+ numOfCache: Int
+ numOfMQ: Int
+}
+
+# Query the trend of alarm rate based on the given duration
+type AlarmTrend {
+ numOfAlarmRate: [Int]!
+}
+
+# Query all conjectural applications based on the given duration
+# All applications here are not installed agent.
+type ConjecturalAppBrief {
+ apps: [ConjecturalApp!]
+}
+
+# The basic info of the conjectural application,
+# includes the type and num of same type application
+type ConjecturalApp {
+ # The display name of the application
+ # e.g. MySQL, RocketMQ, Kafka, Nginx
+ name: String!
+ num: Int!
+}
+
+extend type Query {
+ getClusterTopology(duration: Duration!): Topology
+ getClusterBrief(duration: Duration!): ClusterBrief
+ getAlarmTrend(duration: Duration!): AlarmTrend
+ getConjecturalApps(duration: Duration!): ConjecturalAppBrief
+ getTopNSlowService(duration: Duration!, topN: Int!): [ServiceInfo!]
+ getTopNServerThroughput(duration: Duration!, topN: Int!): [AppServerInfo!]
+}
diff --git a/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/server-layer.graphqls b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/server-layer.graphqls
new file mode 100644
index 000000000..eac33a7dc
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/server-layer.graphqls
@@ -0,0 +1,42 @@
+# The server info.
+# At here, `Server` represents a process in OS,
+# e.g.
+# 1. Spring boot application
+# 2. A Tomcat server instance
+type AppServerInfo {
+ id: ID!
+ name: String!
+ tps: Int!
+ os: String
+ host: String
+ pid: Int
+ IPv4: String
+ IPv6: String
+}
+
+type CPUTrend {
+ cost: [Int!]
+}
+
+# The gc trend represents the numbers of Garbage Collector execution
+type GCTrend {
+ youngGC: [Int!]
+ oldGC: [Int!]
+}
+
+# The memory used and max limit in heap and noheap space.
+type MemoryTrend {
+ heap: [Int!]
+ maxHeap: [Int!]
+ noheap: [Int!]
+ maxNoheap: [Int!]
+}
+
+extend type Query {
+ searchServer(keyword: String!, duration: Duration!): [AppServerInfo]
+ getServerResponseTimeTrend(serverId: ID!, duration: Duration!): ResponseTimeTrend
+ getServerTPSTrend(serverId: ID!, duration: Duration!): ThroughputTrend
+ getCPUTrend(serverId: ID!, duration: Duration!): CPUTrend
+ getGCTrend(serverId: ID!, duration: Duration!): GCTrend
+ getMemoryTrend(serverId: ID!, duration: Duration!): MemoryTrend
+}
\ No newline at end of file
diff --git a/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/service-layer.graphqls b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/service-layer.graphqls
new file mode 100644
index 000000000..3e33c8f9e
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/service-layer.graphqls
@@ -0,0 +1,35 @@
+type ServiceNode implements Node {
+ id: ID!
+ name: String!
+ type: String
+ # Success rate of all incoming requests.
+ # Max value is 100.
+ # 2 Digits after floating point.
+ sla: Float!
+ # The number of incoming calls
+ calls: Long!
+ # The number of services alerting
+ numOfServiceAlarm: Int!
+}
+
+type ServiceInfo {
+ id: ID!
+ name: String
+ # The unit is millisecond.
+ avgResponseTime: Int!
+ tps: Int!
+}
+
+type TraceItem {
+ time: String!
+ entry: String!
+ duration: Int!
+}
+
+extend type Query {
+ searchService(keyword: String!, duration: Duration!): [ServiceNode]
+ getServiceResponseTimeTrend(serviceId: ID!, duration: Duration!): ResponseTimeTrend
+ getServiceTPSTrend(serviceId: ID!, duration: Duration!): ThroughputTrend
+ getServiceSLATrend(serviceId: ID!, duration: Duration!): SLATrend
+ getServiceTopology(serviceId: ID!, duration: Duration!): Topology
+}
diff --git a/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/trace.graphqls b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/trace.graphqls
new file mode 100644
index 000000000..4e2e1a0ec
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/main/resources/ui-graphql/trace.graphqls
@@ -0,0 +1,89 @@
+# The list of traces
+type TraceBrief {
+ traces: [BasicTrace!]
+}
+
+# Trace basic info
+type BasicTrace {
+ operationName: String!
+ duration: Int!
+ start: String!
+ isError: Boolean
+ traceId: String
+}
+
+# Represent the conditions used for query TraceBrief
+input TraceQueryCondition {
+ applicationCodes: [String!]
+ traceId: String
+ operationName: String
+ # The time range of traces started
+ queryDuration: Duration
+ # The mix time of trace
+ minTraceDuration: Int
+ # The max time of trace
+ maxTraceDuration: Int
+ topN: Boolean
+ needTotal: Int
+}
+
+enum QueryOrder {
+ BY_START_TIME
+ BY_DURATION
+}
+
+# The trace represents a distributed trace, includes all segments and spans.
+type Trace {
+ traceId: ID!
+ segments: [Segment!]
+}
+
+type Segment {
+ segmentId: ID!
+ appName: String!
+ isSizeLimited: Boolean!
+ spans: [Span!]!
+}
+
+type Span {
+ refs: [Ref!]
+ spanId: Int!
+ parentSpanId: Int!
+ startTime: Long!
+ endTime: Long!
+ operationName: String
+ # There are three span types: Local, Entry and Exit
+ type: String!
+ # Peer network id, e.g. host+port, ip+port
+ peer: String
+ component: String
+ isError: Boolean
+ # There are 5 layers: Unknown, Database, RPCFramework, Http, MQ and Cache
+ layer: String
+ tags: [KeyValue!]
+ logs: [LogEntity!]
+}
+
+# Ref represents the link between the segment and its parents.
+type Ref {
+ parentSegmentId: ID!
+ parentSpanId: Int!
+ # Ref type represents why did the ref happen.
+ # Include: 1) CrossProcess 2) CrossThread
+ type: String!
+}
+
+type KeyValue {
+ key: String!
+ value: String
+}
+
+type LogEntity {
+ time: String
+ data: [KeyValue!]
+}
+
+extend type Query {
+ queryBasicTraces(condition: TraceQueryCondition): TraceBrief
+ queryTrace(traceId: ID!): Trace
+}
\ No newline at end of file
diff --git a/apm-protocol/apm-ui-protocol/src/test/java/org/apache/skywalking/apm/ui/protocol/GraphQLScriptTest.java b/apm-protocol/apm-ui-protocol/src/test/java/org/apache/skywalking/apm/ui/protocol/GraphQLScriptTest.java
new file mode 100644
index 000000000..f017d6844
--- /dev/null
+++ b/apm-protocol/apm-ui-protocol/src/test/java/org/apache/skywalking/apm/ui/protocol/GraphQLScriptTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ *
+ */
+
+package org.apache.skywalking.apm.ui.protocol;
+
+import graphql.schema.idl.EchoingWiringFactory;
+import graphql.schema.idl.RuntimeWiring;
+import graphql.schema.idl.SchemaGenerator;
+import graphql.schema.idl.SchemaParser;
+import graphql.schema.idl.TypeDefinitionRegistry;
+import java.io.File;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class GraphQLScriptTest {
+
+ @Test
+ public void assertScriptFormat() {
+ SchemaParser schemaParser = new SchemaParser();
+ SchemaGenerator schemaGenerator = new SchemaGenerator();
+
+ TypeDefinitionRegistry typeRegistry = new TypeDefinitionRegistry();
+ typeRegistry.merge(schemaParser.parse(loadSchema("common.graphqls")));
+ typeRegistry.merge(schemaParser.parse(loadSchema("trace.graphqls")));
+ typeRegistry.merge(schemaParser.parse(loadSchema("overview-layer.graphqls")));
+ typeRegistry.merge(schemaParser.parse(loadSchema("application-layer.graphqls")));
+ typeRegistry.merge(schemaParser.parse(loadSchema("server-layer.graphqls")));
+ typeRegistry.merge(schemaParser.parse(loadSchema("service-layer.graphqls")));
+ typeRegistry.merge(schemaParser.parse(loadSchema("alarm.graphqls")));
+ RuntimeWiring wiring = buildRuntimeWiring();
+ assertTrue(schemaGenerator.makeExecutableSchema(typeRegistry, wiring).getAllTypesAsList().size() > 0);
+ }
+
+ private File loadSchema(final String s) {
+ return new File(GraphQLScriptTest.class.getClassLoader().getResource("ui-graphql/" + s).getFile());
+ }
+
+ private RuntimeWiring buildRuntimeWiring() {
+ return RuntimeWiring.newRuntimeWiring().wiringFactory(new EchoingWiringFactory()).build();
+ }
+}
diff --git a/apm-protocol/pom.xml b/apm-protocol/pom.xml
index cc8684970..fa5708532 100644
--- a/apm-protocol/pom.xml
+++ b/apm-protocol/pom.xml
@@ -32,6 +32,6 @@
apm-network
- apm-ui-query
+ apm-ui-protocol
\ No newline at end of file