This is an automated email from the ASF dual-hosted git repository.
casion pushed a commit to branch dev-1.3.1-errorcode
in repository https://gitbox.apache.org/repos/asf/incubator-linkis.git
The following commit(s) were added to refs/heads/dev-1.3.1-errorcode by this
push:
new ab1aff013 [linkis-label-common]module errorcode optimization and
documentation (#3593)
ab1aff013 is described below
commit ab1aff0135ce655874b9d90597a70ba98c5c3a11
Author: 成彬彬 <[email protected]>
AuthorDate: Tue Oct 18 10:28:04 2022 +0800
[linkis-label-common]module errorcode optimization and documentation (#3593)
---
docs/errorcode/linkis-label-common-errorcode.md | 13 ++++
.../impl/DefaultNodeLabelRemoveService.scala | 5 +-
.../service/impl/DefaultUserLabelService.scala | 5 +-
.../label/builder/CombinedLabelBuilder.java | 7 +-
.../label/builder/DefaultGlobalLabelBuilder.java | 12 +--
.../linkis/manager/label/entity/TenantLabel.java | 7 +-
.../manager/label/entity/cluster/EnvLabel.java | 5 +-
.../label/entity/engine/UserCreatorLabel.java | 8 +-
.../manager/label/entity/route/RouteLabel.java | 7 +-
.../errorcode/LabelCommonErrorCodeSummary.java | 87 ++++++++++++++++++++++
10 files changed, 130 insertions(+), 26 deletions(-)
diff --git a/docs/errorcode/linkis-label-common-errorcode.md
b/docs/errorcode/linkis-label-common-errorcode.md
new file mode 100644
index 000000000..cc3636ad5
--- /dev/null
+++ b/docs/errorcode/linkis-label-common-errorcode.md
@@ -0,0 +1,13 @@
+## linkis-label-common errorcode
+
+| module name(模块名) | error code(错误码) | describe(描述) |enumeration name(枚举)|
Exception Class(类名)|
+| -------- | -------- | ----- |-----|-----|
+|linkis-label-common |40001|Update label realtion
failed(更新标签属性失败)|UPDATE_LABEL_FAILED|LabelCommonErrorCodeSummary|
+|linkis-label-common |40001|The value of the label is set incorrectly, only
one value can be set, and the separator symbol '-' cannot be
used(标签的值设置错误,只能设置一个值,不能使用分割符符号 '-')
|LABEL_ERROR_CODE|LabelCommonErrorCodeSummary|
+|linkis-label-common |40001|Failed to build combinedLabel(构建组合标签失败)
|FAILED_BUILD_COMBINEDLABEL|LabelCommonErrorCodeSummary|
+|linkis-label-common |40001|Fail to read value input stream(读取值输入流失败)
|FAILED_READ_INPUT_STREAM|LabelCommonErrorCodeSummary|
+|linkis-label-common |40001|Fail to construct a label instance
of(未能构建标签实例):|FAILED_CONSTRUCT_INSTANCE|LabelCommonErrorCodeSummary|
+|linkis-label-common |40001|Not support envType(不支持
envType):|NOT_SUPPORT_ENVTYPE|LabelCommonErrorCodeSummary|
+|linkis-label-common |130001|ServiceInstance in request is null, please check
label remove request(请求中的 ServiceInstance
为空,请检查标签删除请求)|CHECK_LABEL_REMOVE_REQUEST|LabelCommonErrorCodeSummary|
+
+
diff --git
a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/label/service/impl/DefaultNodeLabelRemoveService.scala
b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/label/service/impl/DefaultNodeLabelRemoveService.scala
index ed62707c9..7dcc38071 100644
---
a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/label/service/impl/DefaultNodeLabelRemoveService.scala
+++
b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/label/service/impl/DefaultNodeLabelRemoveService.scala
@@ -22,6 +22,7 @@ import
org.apache.linkis.manager.common.entity.persistence.PersistenceLabel
import
org.apache.linkis.manager.label.builder.factory.LabelBuilderFactoryContext
import org.apache.linkis.manager.label.entity.em.EMInstanceLabel
import org.apache.linkis.manager.label.entity.engine.EngineInstanceLabel
+import org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary._
import org.apache.linkis.manager.label.exception.LabelRuntimeException
import org.apache.linkis.manager.label.service.{NodeLabelRemoveService,
NodeLabelService}
import org.apache.linkis.manager.persistence.LabelManagerPersistence
@@ -47,8 +48,8 @@ class DefaultNodeLabelRemoveService extends
NodeLabelRemoveService with Logging
logger.info(s"Start to remove labels from node
${nodeLabelRemoveRequest.getServiceInstance}")
if (nodeLabelRemoveRequest.getServiceInstance == null) {
throw new LabelRuntimeException(
- 130001,
- "ServiceInstance in request is null, please check label remove
request!"
+ CHECK_LABEL_REMOVE_REQUEST.getErrorCode,
+ CHECK_LABEL_REMOVE_REQUEST.getErrorDesc
)
}
nodeLabelService.removeLabelsFromNode(nodeLabelRemoveRequest.getServiceInstance)
diff --git
a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/label/service/impl/DefaultUserLabelService.scala
b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/label/service/impl/DefaultUserLabelService.scala
index b0cb0524b..71861019e 100644
---
a/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/label/service/impl/DefaultUserLabelService.scala
+++
b/linkis-computation-governance/linkis-manager/linkis-application-manager/src/main/scala/org/apache/linkis/manager/label/service/impl/DefaultUserLabelService.scala
@@ -22,6 +22,7 @@ import org.apache.linkis.manager.label.LabelManagerUtils
import
org.apache.linkis.manager.label.builder.factory.LabelBuilderFactoryContext
import org.apache.linkis.manager.label.constant.LabelConstant
import org.apache.linkis.manager.label.entity.Label
+import org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary._
import org.apache.linkis.manager.label.exception.LabelErrorException
import org.apache.linkis.manager.label.service.UserLabelService
import org.apache.linkis.manager.persistence.LabelManagerPersistence
@@ -81,8 +82,8 @@ class DefaultUserLabelService extends UserLabelService with
Logging {
.containsAll(userRelationLabels.asScala.map(_.getId).asJava)
) {
throw new LabelErrorException(
- LabelConstant.LABEL_BUILDER_ERROR_CODE,
- "update label realtion failed"
+ UPDATE_LABEL_FAILED.getErrorCode,
+ UPDATE_LABEL_FAILED.getErrorDesc
)
}
}
diff --git
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/builder/CombinedLabelBuilder.java
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/builder/CombinedLabelBuilder.java
index da9a757e8..15e1f9ed0 100644
---
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/builder/CombinedLabelBuilder.java
+++
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/builder/CombinedLabelBuilder.java
@@ -19,7 +19,6 @@ package org.apache.linkis.manager.label.builder;
import org.apache.linkis.manager.label.builder.factory.LabelBuilderFactory;
import
org.apache.linkis.manager.label.builder.factory.LabelBuilderFactoryContext;
-import org.apache.linkis.manager.label.constant.LabelConstant;
import org.apache.linkis.manager.label.constant.LabelKeyConstant;
import org.apache.linkis.manager.label.entity.CombinedLabelImpl;
import org.apache.linkis.manager.label.entity.Label;
@@ -30,6 +29,8 @@ import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
+import static
org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary.FAILED_BUILD_COMBINEDLABEL;
+
public class CombinedLabelBuilder implements LabelBuilder {
private static LabelBuilderFactory labelFactory =
@@ -51,7 +52,9 @@ public class CombinedLabelBuilder implements LabelBuilder {
return new CombinedLabelImpl(labels);
} catch (Throwable e) {
throw new LabelErrorException(
- LabelConstant.LABEL_BUILDER_ERROR_CODE, "Failed to build
combinedLabel", e);
+ FAILED_BUILD_COMBINEDLABEL.getErrorCode(),
+ FAILED_BUILD_COMBINEDLABEL.getErrorDesc(),
+ e);
}
}
return null;
diff --git
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/builder/DefaultGlobalLabelBuilder.java
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/builder/DefaultGlobalLabelBuilder.java
index 4cfe117c9..6947c8754 100644
---
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/builder/DefaultGlobalLabelBuilder.java
+++
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/builder/DefaultGlobalLabelBuilder.java
@@ -18,7 +18,6 @@
package org.apache.linkis.manager.label.builder;
import org.apache.linkis.common.utils.ClassUtils;
-import org.apache.linkis.manager.label.constant.LabelConstant;
import org.apache.linkis.manager.label.entity.InheritableLabel;
import org.apache.linkis.manager.label.entity.Label;
import org.apache.linkis.manager.label.entity.SerializableLabel;
@@ -42,6 +41,9 @@ import java.util.function.Function;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static
org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary.FAILED_CONSTRUCT_INSTANCE;
+import static
org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary.FAILED_READ_INPUT_STREAM;
+
/** To build different types of label */
@SuppressWarnings(value = {"unchecked", "rawtypes"})
public class DefaultGlobalLabelBuilder extends AbstractGenericLabelBuilder {
@@ -135,7 +137,7 @@ public class DefaultGlobalLabelBuilder extends
AbstractGenericLabelBuilder {
labelKey, null == valueInput ? "" : IOUtils.toString(valueInput),
labelClass, valueTypes);
} catch (IOException e) {
throw new LabelErrorException(
- LabelConstant.LABEL_BUILDER_ERROR_CODE, "Fail to read value input
stream", e);
+ FAILED_READ_INPUT_STREAM.getErrorCode(),
FAILED_READ_INPUT_STREAM.getErrorDesc(), e);
}
}
@@ -147,7 +149,7 @@ public class DefaultGlobalLabelBuilder extends
AbstractGenericLabelBuilder {
labelKey, null == valueInput ? "" : IOUtils.toString(valueInput),
(Class<?>) labelClass);
} catch (IOException e) {
throw new LabelErrorException(
- LabelConstant.LABEL_BUILDER_ERROR_CODE, "Fail to read value input
stream", e);
+ FAILED_READ_INPUT_STREAM.getErrorCode(),
FAILED_READ_INPUT_STREAM.getErrorDesc(), e);
}
}
@@ -285,8 +287,8 @@ public class DefaultGlobalLabelBuilder extends
AbstractGenericLabelBuilder {
return newLabel;
} catch (InstantiationException | IllegalAccessException |
InvocationTargetException e) {
throw new LabelErrorException(
- LabelConstant.LABEL_BUILDER_ERROR_CODE,
- "Fail to construct a label instance of [" +
labelType.getSimpleName() + "]",
+ FAILED_CONSTRUCT_INSTANCE.getErrorCode(),
+ FAILED_CONSTRUCT_INSTANCE.getErrorDesc() + labelType.getSimpleName(),
e);
}
}
diff --git
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/TenantLabel.java
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/TenantLabel.java
index 62149cb1f..bf0f03fec 100644
---
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/TenantLabel.java
+++
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/TenantLabel.java
@@ -17,7 +17,6 @@
package org.apache.linkis.manager.label.entity;
-import org.apache.linkis.manager.label.constant.LabelConstant;
import org.apache.linkis.manager.label.constant.LabelKeyConstant;
import org.apache.linkis.manager.label.entity.annon.ValueSerialNum;
import org.apache.linkis.manager.label.exception.LabelErrorException;
@@ -26,6 +25,8 @@ import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
+import static
org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary.LABEL_ERROR_CODE;
+
public class TenantLabel extends GenericLabel
implements EMNodeLabel, EngineNodeLabel, UserModifiable {
@@ -63,9 +64,7 @@ public class TenantLabel extends GenericLabel
if (!StringUtils.isEmpty(stringValue)) {
if (stringValue.split(SerializableLabel.VALUE_SEPARATOR).length != 1) {
throw new LabelErrorException(
- LabelConstant.LABEL_BUILDER_ERROR_CODE,
- "The value of the label is set incorrectly, only one value can be
set, and the symbol cannot be used"
- + VALUE_SEPARATOR);
+ LABEL_ERROR_CODE.getErrorCode(), LABEL_ERROR_CODE.getErrorDesc());
}
}
}
diff --git
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/cluster/EnvLabel.java
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/cluster/EnvLabel.java
index aaab73286..188e63d89 100644
---
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/cluster/EnvLabel.java
+++
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/cluster/EnvLabel.java
@@ -23,8 +23,8 @@ import
org.apache.linkis.manager.label.exception.LabelRuntimeException;
import java.util.HashMap;
-import static
org.apache.linkis.manager.label.constant.LabelConstant.LABEL_BUILDER_ERROR_CODE;
import static
org.apache.linkis.manager.label.constant.LabelKeyConstant.ENV_TYPE_KEY;
+import static
org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary.NOT_SUPPORT_ENVTYPE;
public class EnvLabel extends GenericLabel {
@@ -43,7 +43,8 @@ public class EnvLabel extends GenericLabel {
public void setEnvType(String envType) {
if (!envType.equals(DEV) && !envType.equals(TEST) &&
!envType.equals(PROD)) {
- throw new LabelRuntimeException(LABEL_BUILDER_ERROR_CODE, "Not support
envType: " + envType);
+ throw new LabelRuntimeException(
+ NOT_SUPPORT_ENVTYPE.getErrorCode(),
NOT_SUPPORT_ENVTYPE.getErrorDesc() + envType);
}
if (null == getValue()) {
setValue(new HashMap<>());
diff --git
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/engine/UserCreatorLabel.java
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/engine/UserCreatorLabel.java
index 8ade1e70e..b68768059 100644
---
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/engine/UserCreatorLabel.java
+++
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/engine/UserCreatorLabel.java
@@ -17,7 +17,6 @@
package org.apache.linkis.manager.label.entity.engine;
-import org.apache.linkis.manager.label.constant.LabelConstant;
import org.apache.linkis.manager.label.constant.LabelKeyConstant;
import org.apache.linkis.manager.label.entity.*;
import org.apache.linkis.manager.label.entity.annon.ValueSerialNum;
@@ -27,6 +26,8 @@ import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
+import static
org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary.LABEL_ERROR_CODE;
+
public class UserCreatorLabel extends GenericLabel implements EngineNodeLabel,
UserModifiable {
public UserCreatorLabel() {
@@ -78,10 +79,7 @@ public class UserCreatorLabel extends GenericLabel
implements EngineNodeLabel, U
if (!StringUtils.isEmpty(stringValue)) {
if (stringValue.split(SerializableLabel.VALUE_SEPARATOR).length != 2) {
throw new LabelErrorException(
- LabelConstant.LABEL_BUILDER_ERROR_CODE,
- "The value of the label is set incorrectly, only one value can be
set, and the symbol cannot be used"
- + VALUE_SEPARATOR
- + "隔开");
+ LABEL_ERROR_CODE.getErrorCode(), LABEL_ERROR_CODE.getErrorDesc());
}
}
}
diff --git
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/route/RouteLabel.java
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/route/RouteLabel.java
index 8791739e4..3f69e2e2c 100644
---
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/route/RouteLabel.java
+++
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/entity/route/RouteLabel.java
@@ -17,7 +17,6 @@
package org.apache.linkis.manager.label.entity.route;
-import org.apache.linkis.manager.label.constant.LabelConstant;
import org.apache.linkis.manager.label.constant.LabelKeyConstant;
import org.apache.linkis.manager.label.entity.InheritableLabel;
import org.apache.linkis.manager.label.entity.SerializableLabel;
@@ -27,6 +26,8 @@ import
org.apache.linkis.manager.label.exception.LabelErrorException;
import org.apache.commons.lang3.StringUtils;
+import static
org.apache.linkis.manager.label.errorcode.LabelCommonErrorCodeSummary.LABEL_ERROR_CODE;
+
public class RouteLabel extends InheritableLabel<String> implements
UserModifiable {
public RouteLabel() {
@@ -48,9 +49,7 @@ public class RouteLabel extends InheritableLabel<String>
implements UserModifiab
if (!StringUtils.isEmpty(stringValue)) {
if (stringValue.split(SerializableLabel.VALUE_SEPARATOR).length != 1) {
throw new LabelErrorException(
- LabelConstant.LABEL_BUILDER_ERROR_CODE,
- "The value of the label is set incorrectly, only 1 value can be
set, and the symbol cannot be used"
- + VALUE_SEPARATOR);
+ LABEL_ERROR_CODE.getErrorCode(), LABEL_ERROR_CODE.getErrorDesc());
}
}
}
diff --git
a/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/errorcode/LabelCommonErrorCodeSummary.java
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/errorcode/LabelCommonErrorCodeSummary.java
new file mode 100644
index 000000000..607d45e20
--- /dev/null
+++
b/linkis-computation-governance/linkis-manager/linkis-label-common/src/main/java/org/apache/linkis/manager/label/errorcode/LabelCommonErrorCodeSummary.java
@@ -0,0 +1,87 @@
+/*
+ * 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.linkis.manager.label.errorcode;
+
+public enum LabelCommonErrorCodeSummary {
+ UPDATE_LABEL_FAILED(
+ 40001, "Update label realtion failed(更新标签属性失败)", "Update label realtion
failed(更新标签属性失败)"),
+ LABEL_ERROR_CODE(
+ 40001,
+ "The value of the label is set incorrectly, only one value can be set,
and the separator symbol '-' cannot be used(标签的值设置错误,只能设置一个值,不能使用分割符符号 '-') ",
+ "The value of the label is set incorrectly, only one value can be set,
and the separator symbol '-' cannot be used(标签的值设置错误,只能设置一个值,不能使用分割符符号 '-') "),
+ FAILED_BUILD_COMBINEDLABEL(
+ 40001,
+ "Failed to build combinedLabel(构建组合标签失败) ",
+ "Failed to build combinedLabel(构建组合标签失败) "),
+ FAILED_READ_INPUT_STREAM(
+ 40001,
+ "Fail to read value input stream(读取值输入流失败) ",
+ "Fail to read value input stream(读取值输入流失败) "),
+ FAILED_CONSTRUCT_INSTANCE(
+ 40001,
+ "Fail to construct a label instance of(未能构建标签实例):",
+ "Fail to construct a label instance of(未能构建标签实例):"),
+ NOT_SUPPORT_ENVTYPE(
+ 40001, "Not support envType(不支持 envType):", "Not support envType(不支持
envType):"),
+ CHECK_LABEL_REMOVE_REQUEST(
+ 130001,
+ "ServiceInstance in request is null, please check label remove
request(请求中的 ServiceInstance 为空,请检查标签删除请求)",
+ "ServiceInstance in request is null, please check label remove
request(请求中的 ServiceInstance 为空,请检查标签删除请求)");
+
+ /** (errorCode)错误码 */
+ private int errorCode;
+ /** (errorDesc)错误描述 */
+ private String errorDesc;
+ /** Possible reasons for the error(错误可能出现的原因) */
+ private String comment;
+
+ LabelCommonErrorCodeSummary(int errorCode, String errorDesc, String comment)
{
+ this.errorCode = errorCode;
+ this.errorDesc = errorDesc;
+ this.comment = comment;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public void setErrorCode(int errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public String getErrorDesc() {
+ return errorDesc;
+ }
+
+ public void setErrorDesc(String errorDesc) {
+ this.errorDesc = errorDesc;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ @Override
+ public String toString() {
+ return "errorCode: " + this.errorCode + ", errorDesc:" + this.errorDesc;
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]