Authored by qinchao

Merge branch 'hotfix_超时' into test6.8.6

package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.OrderOverTime;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface OrderOverTimeMapper {
int insertDeliveryTime(OrderOverTime record);
int insertShamSendTime(OrderOverTime record);
List<OrderOverTime> selectByOrderCodes(@Param(value = "orderCodeList") List<Long> orderCodeList);
OrderOverTime selectByOrderCode(@Param(value = "orderCode")Long orderCode);
}
\ No newline at end of file
... ...
package com.yohoufo.dal.order.model;
import com.alibaba.fastjson.JSONObject;
public class OrderOverTime {
private Integer id;
private Long orderCode;
private Integer deliveryTime;
private Integer deliveryMinutes;
private Integer shamSendTime;
public OrderOverTime() {
}
public OrderOverTime(Long orderCode, Integer deliveryTime, Integer deliveryMinute) {
this.orderCode = orderCode;
this.deliveryTime = deliveryTime;
this.deliveryMinutes = deliveryMinute;
}
public OrderOverTime(Integer shamSendTime, Long orderCode) {
this.shamSendTime = shamSendTime;
this.orderCode = orderCode;
}
public Integer getDeliveryMinutes() {
return deliveryMinutes;
}
public void setDeliveryMinutes(Integer deliveryMinutes) {
this.deliveryMinutes = deliveryMinutes;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Long getOrderCode() {
return orderCode;
}
public void setOrderCode(Long orderCode) {
this.orderCode = orderCode;
}
public Integer getDeliveryTime() {
return deliveryTime;
}
public void setDeliveryTime(Integer deliveryTime) {
this.deliveryTime = deliveryTime;
}
public Integer getShamSendTime() {
return shamSendTime;
}
public void setShamSendTime(Integer shamSendTime) {
this.shamSendTime = shamSendTime;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.yohoufo.dal.order.OrderOverTimeMapper" >
<resultMap id="BaseResultMap" type="com.yohoufo.dal.order.model.OrderOverTime" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="order_code" property="orderCode" jdbcType="BIGINT" />
<result column="delivery_time" property="deliveryTime" jdbcType="INTEGER" />
<result column="delivery_minutes" property="deliveryMinutes" jdbcType="INTEGER" />
<result column="sham_send_time" property="shamSendTime" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List" >
id, order_code, delivery_time, delivery_minutes, sham_send_time
</sql>
<insert id="insertDeliveryTime" parameterType="com.yohoufo.dal.order.model.OrderOverTime" >
insert into order_over_time (order_code, delivery_time, delivery_minutes)
values (#{orderCode,jdbcType=BIGINT}, #{deliveryTime,jdbcType=INTEGER}, #{deliveryMinutes,jdbcType=INTEGER})
ON DUPLICATE KEY UPDATE delivery_time = #{deliveryTime, jdbcType=INTEGER}, delivery_minutes = #{deliveryMinutes,jdbcType=INTEGER}
</insert>
<insert id="insertShamSendTime" parameterType="com.yohoufo.dal.order.model.OrderOverTime" >
insert into order_over_time (order_code, sham_send_time)
values (#{orderCode,jdbcType=BIGINT}, #{shamSendTime,jdbcType=INTEGER})
ON DUPLICATE KEY UPDATE sham_send_time = #{shamSendTime,jdbcType=INTEGER}
</insert>
<select id="selectByOrderCodes" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from order_over_time
where order_code IN
<foreach collection="orderCodeList" open="(" close=")" separator="," item="item">
#{item, jdbcType=BIGINT}
</foreach>
</select>
<select id="selectByOrderCode" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from order_over_time where order_code = #{orderCode, jdbcType=BIGINT}
</select>
</mapper>
\ No newline at end of file
... ...
... ... @@ -20,4 +20,6 @@ public interface DelayTime {
//瑕疵等待用户确认的超时时间,24小时
int MINI_FAULT_CONFIRM_OUTER_TIME_MINUTE=24*60;
int MINUTES_120_HOURS = 120 * 60;
}
... ...
... ... @@ -18,7 +18,7 @@ public class SellerOrderCancelDeliverDelayMsgConsumer120 extends JsonObjectMessa
@Override
public String getTopic() {
return TopicConstants.SELLER_ORDER_AUTO_CANCEL_DELIVER_120;
return TopicConstants.SELLER_ORDER_AUTO_CANCEL_DELIVER;
}
@Override
... ...
... ... @@ -36,8 +36,7 @@ public class DeliverNoticeAsyncHandler implements IEventHandler<DeliverNoticeEve
@Subscribe
public void handle(DeliverNoticeEvent event) {
int minutes = deliveryMinutesService.getDeliverMinutesSecond();
//String topic = TopicConstants.ORDER_NOT_DELIVER_NOTICE;
String topic = TopicConstants.ORDER_NOT_DELIVER_NOTICE_108;
String topic = TopicConstants.ORDER_NOT_DELIVER_NOTICE;
logger.info("in DeliverNoticeAsyncHandler handler, topic {},minutes {} ,msg {}",topic, minutes,event);
tradeMqSender.send(topic, event, minutes);
}
... ...
... ... @@ -3,10 +3,13 @@ package com.yohoufo.order.service.handler;
import com.google.common.eventbus.Subscribe;
import com.yoho.core.config.ConfigReader;
import com.yohoufo.common.alarm.IEventHandler;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.model.OrderOverTime;
import com.yohoufo.order.event.SellerCancelDeliverEvent;
import com.yohoufo.order.mq.DelayTime;
import com.yohoufo.order.mq.TopicConstants;
import com.yohoufo.order.mq.producer.TradeMqSender;
import com.yohoufo.order.service.impl.OrderOverTimeService;
import com.yohoufo.order.service.proxy.DeliveryMinutesService;
import com.yohoufo.order.utils.LoggerUtils;
import org.slf4j.Logger;
... ... @@ -29,14 +32,19 @@ public class SellerCancelDeliverHandler implements IEventHandler<SellerCancelDel
@Autowired
private DeliveryMinutesService deliveryMinutesService;
@Autowired
private OrderOverTimeService orderOverTimeService;
@Override
@Subscribe
public void handle(SellerCancelDeliverEvent event) {
int minutes = deliveryMinutesService.getDeliverMinutesThird();
//String topic = TopicConstants.SELLER_ORDER_AUTO_CANCEL_DELIVER;
String topic = TopicConstants.SELLER_ORDER_AUTO_CANCEL_DELIVER_120;
String topic = TopicConstants.SELLER_ORDER_AUTO_CANCEL_DELIVER;
logger.info("Subscribe Buyer Confirm delay msg,topic {}, delay minutes {} , event {}",topic,minutes, event);
tradeMqSender.send(topic, event, minutes);
// 记录此订单的发货超时时间期限点
orderOverTimeService.insertDeliveryTime(new OrderOverTime(event.getOrderCode(), DateUtil.getCurrentTimeSecond() + minutes * 60, minutes));
}
}
... ...
... ... @@ -48,9 +48,6 @@ public abstract class AbsOrderDetailService extends AbsOrderViewService implemen
@Autowired
protected OrdersPayService ordersPayService;
@Autowired
private DeliveryMinutesService deliveryMinutesService;
abstract BuyerOrder getBuyerOrder(int uid, long orderCode);
abstract BuyerOrderMeta getBuyerOrderMeta(int uid, long orderCode, String metaKey);
... ... @@ -110,15 +107,6 @@ public abstract class AbsOrderDetailService extends AbsOrderViewService implemen
throw new ServiceException(ServiceError.ORDER_STATUS_INVALIDATE);
}
/*if(orderStatus.getCode() == OrderStatus.HAS_PAYED.getCode() || orderStatus.getCode() == OrderStatus.SEND_OUT_TIMEOUT.getCode()){
TimeoutBo timeoutBo = ordersPayService.getDeliverLeftTime(uid, orderCode);
if(timeoutBo!=null && timeoutBo.getTimelimit().intValue() != DelayTime.MINUTES_36_HOURS * 60
&& timeoutBo.getStartTime()!=null && timeoutBo.getStartTime().intValue()>=deliveryMinutesService.getOnlineTime()){
logger.info("getOrderDetail resetDescForSeller , uid is {}, buyerUid {} orderCode is {}", uid,
buyerUid, orderCode);
OrderStatus.resetDescForSeller(orderStatus);
}
}*/
BuyerOrderGoods buyerOrderGoods = getBuyerOrderGoods(buyerUid, orderCode);
if (buyerOrderGoods == null){
... ...
package com.yohoufo.order.service.impl;
import com.yohoufo.dal.order.OrderOverTimeMapper;
import com.yohoufo.dal.order.model.OrderOverTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Created by li.ma on 2019/1/30.
*/
@Service
public class OrderOverTimeService {
@Autowired
private OrderOverTimeMapper orderOverTimeMapper;
public int insertDeliveryTime(OrderOverTime record) {
return orderOverTimeMapper.insertDeliveryTime(record);
}
public int insertShamSendTime(OrderOverTime record) {
return orderOverTimeMapper.insertShamSendTime(record);
}
public List<OrderOverTime> selectByOrderCodes(List<Long> orderCodeList) {
return orderOverTimeMapper.selectByOrderCodes(orderCodeList);
}
public OrderOverTime selectByOrderCode(Long orderCode) {
return orderOverTimeMapper.selectByOrderCode(orderCode);
}
}
... ...
... ... @@ -4,6 +4,7 @@ import com.yohobuy.ufo.model.order.bo.TimeoutBo;
import com.yohobuy.ufo.model.order.constants.TimeoutCase;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.dal.order.OrdersPayMapper;
import com.yohoufo.dal.order.model.OrderOverTime;
import com.yohoufo.dal.order.model.OrdersPay;
import com.yohoufo.order.mq.DelayTime;
import com.yohoufo.order.service.proxy.DeliveryMinutesService;
... ... @@ -12,6 +13,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Objects;
import java.util.Optional;
/**
* Created by chao.chen on 2018/11/23.
*/
... ... @@ -24,8 +28,15 @@ public class OrdersPayService {
@Autowired
private DeliveryMinutesService deliveryMinutesService;
@Autowired
private OrderOverTimeService orderOverTimeService;
/**
* 需要根据配置进行算配置时间点之前的剩余时长
* @param buyerUid
* @param orderCode
* @return
*/
public TimeoutBo getDeliverLeftTime(int buyerUid, long orderCode){
OrdersPay ordersPay = ordersPayMapper.selectOrdersPay(orderCode, buyerUid);
if (ordersPay == null){
... ... @@ -34,18 +45,26 @@ public class OrdersPayService {
Integer createTime = ordersPay.getCreateTime();
OrderOverTime orderOverTime = Optional.ofNullable(orderCode).map(orderOverTimeService::selectByOrderCode).orElse(null);
//Integer deliverMinute = Optional.ofNullable(orderOverTime).map(OrderOverTime::getDeliveryMinutes).orElse(null); // 对于老订单来说,超时表记录无数据,则默认120小时
Integer deliverMinute = Optional.ofNullable(orderOverTime).map(OrderOverTime::getDeliveryMinutes).orElse(DelayTime.MINUTES_120_HOURS * 60); // 对于老订单来说,超时表记录无数据,则默认120小时
//把分钟转为秒
int timelimit = deliverMinute * 60;
/**
//订单的支付时间如果大于上线时间,则120小时算,否则还是36小时
int timelimit;
int onLineTime = deliveryMinutesService.getOnlineTime();
if(createTime.intValue()>=onLineTime){
int onLineTime = deliveryMinutesService.getOnlineTime(); //
if(Objects.isNull(deliverMinute)){
logger.info("OrdersPayService createTime bigger than online time ,set 120 hours ,orderCode {},createTime {} ,onLineTime {}",orderCode,createTime,onLineTime);
timelimit = deliveryMinutesService.getDeliverMinutesThird()* 60;
timelimit = DelayTime.MINUTES_120_HOURS * 60;
}else{
logger.info("OrdersPayService createTime smaller than online time ,set 36 hours ,orderCode {},createTime {} ,onLineTime {}",orderCode,createTime,onLineTime);
timelimit = DelayTime.MINUTES_36_HOURS * 60;
//timelimit = deliveryMinutesService.getDeliverMinutesThird()* 60;
timelimit = deliverMinute;
}
//int timelimit = DelayTime.MINUTES_36_HOURS * 60;
//int timelimit = deliveryMinutesService.getDeliverMinutesThird()* 60;
*/
int left = timelimit - (DateUtil.getCurrentTimeSecond()-createTime);
TimeoutBo timeoutBo = new TimeoutBo();
... ...
... ... @@ -42,10 +42,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
/**
* Created by chenchao on 2018/9/20.
... ... @@ -93,7 +90,7 @@ public class SellerOrderDetailService extends AbsOrderDetailService implements I
@Autowired
private DeliveryMinutesService deliveryMinutesService;
private OrderOverTimeService orderOverTimeService;
private static List<SkupStatus> noNeedShowOrderCode = Arrays.asList(SkupStatus.CAN_NOT_SELL,SkupStatus.CAN_SELL,
SkupStatus.SELF_CANCEL_PAY, SkupStatus.TIMEOUT_CANCEL,
... ... @@ -395,14 +392,18 @@ public class SellerOrderDetailService extends AbsOrderDetailService implements I
.build();
if(orderStatus.getCode() == OrderStatus.HAS_PAYED.getCode() || orderStatus.getCode() == OrderStatus.SEND_OUT_TIMEOUT.getCode()){
TimeoutBo timeoutBo = ordersPayService.getDeliverLeftTime(buyerOrder.getUid(), buyerOrder.getOrderCode());
if(timeoutBo!=null && timeoutBo.getTimelimit().intValue() != DelayTime.MINUTES_36_HOURS * 60
&& timeoutBo.getStartTime()!=null && timeoutBo.getStartTime().intValue()>=deliveryMinutesService.getOnlineTime()){
logger.info("getStatusDetail resetDescForSeller , buyerUid {} orderCode is {},statusDetail {}", buyerOrder.getUid(),
buyerOrder.getOrderCode(),statusDetail);
//TimeoutBo timeoutBo = ordersPayService.getDeliverLeftTime(buyerOrder.getUid(), buyerOrder.getOrderCode());
//orderOverTimeService
OrderOverTime orderOverTime = Optional.ofNullable(buyerOrder.getOrderCode()).map(orderOverTimeService::selectByOrderCode).orElse(null);
Integer deliverMinute = Optional.ofNullable(orderOverTime).map(OrderOverTime::getDeliveryMinutes).orElse(DelayTime.MINUTES_120_HOURS * 60); // 对于老订单来说,超时表记录无数据,则默认120小时
int delayHours = deliverMinute/60 ;//发货延迟的时间 : 单位 分钟
logger.info("getStatusDetail resetDescForSeller , buyerUid {} orderCode is {},statusDetail {},orderOverTime {}, deliverMinute {} ", buyerOrder.getUid(),
buyerOrder.getOrderCode(),statusDetail,orderOverTime,deliverMinute);
if(delayHours!=36){
statusDetail.setDetailDesc(statusDetail.getDetailDesc().replace("36","120"));
logger.info("getStatusDetail resetDescForSeller after, buyerUid {} orderCode is {},statusDetail {}", buyerOrder.getUid(),
buyerOrder.getOrderCode(),statusDetail);
logger.info("getStatusDetail resetDescForSeller after, buyerUid {} orderCode is {},statusDetail {},orderOverTime {} ", buyerOrder.getUid(),
buyerOrder.getOrderCode(),statusDetail,orderOverTime);
}
}
... ...
... ... @@ -14,6 +14,7 @@ import com.yohoufo.order.service.impl.AppraiseAddressService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
... ... @@ -26,6 +27,27 @@ import java.util.concurrent.TimeUnit;
@Component
public class DeliveryMinutesService {
private static final Logger logger = LoggerFactory.getLogger(DeliveryMinutesService.class);
@Value("${mq.seller.deliverNotice.second}")
private int minutes_deliverNotice_second;
@Value("${mq.seller.deliverNotice.third}")
private int minutes_deliverNotice_third;
public int getDeliverMinutesSecond(){
return minutes_deliverNotice_second;
}
public int getDeliverMinutesThird(){
return minutes_deliverNotice_third;
}
public int getDeliverMinutesThird_hours(){
int minutes = getDeliverMinutesThird();
return minutes/60 ;
}
/**
@Autowired
private ConfigReader configReader;
... ... @@ -43,7 +65,7 @@ public class DeliveryMinutesService {
private void init() {
localCache_onlineTime.init(ONLINE_TIME_CACHE_KEY, 8, TimeUnit.HOURS, (String s, Object o) -> {
logger.info("init ONLINE_TIME_CACHE_KEY s = {}, o = {}", s, o);
return configReader.getInt("ufo.order.sellerDeliverNewOnlineTime",1548756000);
return configReader.getInt("ufo.order.sellerDeliverNewOnlineTimeEx",1550073600);
});
localCache_second.init(SECOND_CACHE_KEY, 9, TimeUnit.HOURS, (String s, Object o) -> {
... ... @@ -73,10 +95,7 @@ public class DeliveryMinutesService {
return (Integer) value;
}
/**
* 发货时间 : 单位小时
* @return
*/
public int getDeliverMinutesThird_hours(){
int minutes = getDeliverMinutesThird();
return minutes/60 ;
... ... @@ -86,10 +105,9 @@ public class DeliveryMinutesService {
public int getOnlineTime(){
Object value=localCache_onlineTime.get(ONLINE_TIME_CACHE_KEY);
if(null == value) {
return 1548756000;
return 1550073600;
}
return (Integer) value;
}
*/
}
... ...
... ... @@ -123,7 +123,10 @@ rabbit_host=192.168.102.45:5672
rabbit_user=yoho
rabbit_password=yoho
#二次发货提醒 24*60 minutes
mq.seller.deliverNotice.second=1440
#发货失败提醒 36*60 minutes
mq.seller.deliverNotice.third=2160
yoho.gateway.url=http://api-test3.dev.yohocorp.com
... ...
... ... @@ -79,6 +79,7 @@ datasources:
- com.yohoufo.dal.order.SellerEnterApplyMapper
- com.yohoufo.dal.order.SellerFuncMapper
- com.yohoufo.dal.order.SellerLevelFuncMapper
- com.yohoufo.dal.order.OrderOverTimeMapper
ufo_promotion:
servers:
... ...
... ... @@ -18,4 +18,6 @@ ufo.order.sellerDeliverNoticeSecond = 6480
#发货失败提醒 120*60 minutes
ufo.order.sellerDeliverNoticeThird = 7200
#新的发货上线时间 20190129 18:00:00
ufo.order.sellerDeliverNewOnlineTime = 1548756000
\ No newline at end of file
ufo.order.sellerDeliverNewOnlineTime = 1548756000
ufo.order.sellerDeliverNewOnlineTimeEx = 1550073600
\ No newline at end of file
... ...
... ... @@ -23,11 +23,6 @@ consumer:
delay:
interval: 1440
- class: com.yohoufo.order.mq.consumer.SellerOrderCancelDeliverDelayMsgConsumer
topic: sellerOrder.autoCancelDeliver
delay:
interval: 2160
- class: com.yohoufo.order.mq.consumer.NotPaidNoticeDelayMsgConsumer
topic: order.notPaidNotice
delay:
... ... @@ -38,18 +33,23 @@ consumer:
delay:
interval: 1440
#春节期间发货时间延长的120小时
- class: com.yohoufo.order.mq.consumer.SellerOrderCancelDeliverDelayMsgConsumer120
topic: sellerOrder.autoCancelDeliver_120
- class: com.yohoufo.order.mq.consumer.SellerOrderCancelDeliverDelayMsgConsumer
topic: sellerOrder.autoCancelDeliver
delay:
interval: 7200
interval: 2160
#春节期间二次发货提醒时间延长的108小时
#春节期间二次发货提醒时间延长的108小时 ,后续不再使用,6.8.6以后的版本可以去掉
- class: com.yohoufo.order.mq.consumer.NotDeliverNoticeDelayMsgConsumer
topic: order.notDeliver_108
delay:
interval: 6480
#春节期间发货时间延长的120小时 ,后续不再使用,6.8.6以后的版本可以去掉
- class: com.yohoufo.order.mq.consumer.SellerOrderCancelDeliverDelayMsgConsumer120
topic: sellerOrder.autoCancelDeliver_120
delay:
interval: 7200
#更新物流调拨信息
- address: 192.168.102.45:5672
username: yoho
... ...
... ... @@ -98,7 +98,10 @@ rabbit_host=${rabbit_ufo}
rabbit_user=${rabbit_ufo_user}
rabbit_password=${rabbit_ufo_password}
#二次发货提醒 24*60 minutes 1440
mq.seller.deliverNotice.second=${mq.seller.deliverNotice.second}
#发货失败提醒 36*60 minutes 2160
mq.seller.deliverNotice.third=${mq.seller.deliverNotice.third}
yoho.gateway.url=${yoho.gateway.url}
... ...
... ... @@ -79,6 +79,7 @@ datasources:
- com.yohoufo.dal.order.SellerEnterApplyMapper
- com.yohoufo.dal.order.SellerFuncMapper
- com.yohoufo.dal.order.SellerLevelFuncMapper
- com.yohoufo.dal.order.OrderOverTimeMapper
ufo_promotion:
servers:
... ...
... ... @@ -23,11 +23,6 @@ consumer:
delay:
interval: 1440
- class: com.yohoufo.order.mq.consumer.SellerOrderCancelDeliverDelayMsgConsumer
topic: sellerOrder.autoCancelDeliver
delay:
interval: 2160
#order.notPaidNotice
- class: com.yohoufo.order.mq.consumer.NotPaidNoticeDelayMsgConsumer
topic: order.notPaidNotice
... ... @@ -37,20 +32,25 @@ consumer:
- class: com.yohoufo.order.mq.consumer.NotDeliverNoticeDelayMsgConsumer
topic: order.notDeliver
delay:
interval: 1440
interval: ${mq.seller.deliverNotice.second}
#春节期间发货时间延长的120小时
- class: com.yohoufo.order.mq.consumer.SellerOrderCancelDeliverDelayMsgConsumer120
topic: sellerOrder.autoCancelDeliver_120
- class: com.yohoufo.order.mq.consumer.SellerOrderCancelDeliverDelayMsgConsumer
topic: sellerOrder.autoCancelDeliver
delay:
interval: 7200
interval: ${mq.seller.deliverNotice.third}
#春节期间二次发货提醒时间延长的108小时
#春节期间二次发货提醒时间延长的108小时 ,后续不再使用,6.8.6以后的版本可以去掉
- class: com.yohoufo.order.mq.consumer.NotDeliverNoticeDelayMsgConsumer
topic: order.notDeliver_108
delay:
interval: 6480
#春节期间发货时间延长的120小时 ,后续不再使用,6.8.6以后的版本可以去掉
- class: com.yohoufo.order.mq.consumer.SellerOrderCancelDeliverDelayMsgConsumer120
topic: sellerOrder.autoCancelDeliver_120
delay:
interval: 7200
- address: ${rabbit_ufo}
username: ${rabbit_ufo_user}
password: ${rabbit_ufo_password}
... ...