Merge "Bug 509: Improve logging in InMemoryDataStore."
[controller.git] / opendaylight / netconf / netconf-impl / src / main / java / org / opendaylight / controller / netconf / impl / NetconfServerSession.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.netconf.impl;
10
11 import java.text.SimpleDateFormat;
12 import java.util.Date;
13 import java.util.regex.Matcher;
14 import java.util.regex.Pattern;
15
16 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
17 import org.opendaylight.controller.netconf.util.AbstractNetconfSession;
18 import org.opendaylight.controller.netconf.util.handler.NetconfEXICodec;
19 import org.opendaylight.controller.netconf.util.handler.NetconfEXIToMessageDecoder;
20 import org.opendaylight.controller.netconf.util.handler.NetconfMessageToEXIEncoder;
21 import org.opendaylight.controller.netconf.util.handler.NetconfMessageToXMLEncoder;
22 import org.opendaylight.controller.netconf.util.handler.NetconfXMLToMessageDecoder;
23 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.DomainName;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.NetconfTcp;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.Session1Builder;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfSsh;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.Transport;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.SessionBuilder;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.SessionKey;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.DateAndTime;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.ZeroBasedCounter32;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39 import com.google.common.base.Preconditions;
40 import io.netty.channel.Channel;
41
42 public final class NetconfServerSession extends AbstractNetconfSession<NetconfServerSession, NetconfServerSessionListener> implements NetconfManagementSession {
43
44     private static final Logger logger = LoggerFactory.getLogger(NetconfServerSession.class);
45
46     private final NetconfHelloMessageAdditionalHeader header;
47
48     private Date loginTime;
49     private long inRpcSuccess, inRpcFail, outRpcError;
50
51     public NetconfServerSession(NetconfServerSessionListener sessionListener, Channel channel, long sessionId,
52             NetconfHelloMessageAdditionalHeader header) {
53         super(sessionListener, channel, sessionId);
54         this.header = header;
55         logger.debug("Session {} created", toString());
56     }
57
58     @Override
59     protected void sessionUp() {
60         super.sessionUp();
61         Preconditions.checkState(loginTime == null, "Session is already up");
62         this.loginTime = new Date();
63     }
64
65     public void onIncommingRpcSuccess() {
66         inRpcSuccess++;
67     }
68
69     public void onIncommingRpcFail() {
70         inRpcFail++;
71     }
72
73     public void onOutgoingRpcError() {
74         outRpcError++;
75     }
76
77     public static final String ISO_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
78
79     private static final String dateTimePatternString = DateAndTime.PATTERN_CONSTANTS.get(0);
80     private static final Pattern dateTimePattern = Pattern.compile(dateTimePatternString);
81
82     @Override
83     public Session toManagementSession() {
84         SessionBuilder builder = new SessionBuilder();
85
86         builder.setSessionId(getSessionId());
87         builder.setSourceHost(new Host(new DomainName(header.getAddress())));
88
89         Preconditions.checkState(DateAndTime.PATTERN_CONSTANTS.size() == 1);
90         String formattedDateTime = formatDateTime(loginTime);
91
92         Matcher matcher = dateTimePattern.matcher(formattedDateTime);
93         Preconditions.checkState(matcher.matches(), "Formatted datetime %s does not match pattern %s", formattedDateTime, dateTimePattern);
94         builder.setLoginTime(new DateAndTime(formattedDateTime));
95
96         builder.setInBadRpcs(new ZeroBasedCounter32(inRpcFail));
97         builder.setInRpcs(new ZeroBasedCounter32(inRpcSuccess));
98         builder.setOutRpcErrors(new ZeroBasedCounter32(outRpcError));
99
100         builder.setUsername(header.getUserName());
101         builder.setTransport(getTransportForString(header.getTransport()));
102
103         builder.setOutNotifications(new ZeroBasedCounter32(0L));
104
105         builder.setKey(new SessionKey(getSessionId()));
106
107         Session1Builder builder1 = new Session1Builder();
108         builder1.setSessionIdentifier(header.getSessionIdentifier());
109         builder.addAugmentation(Session1.class, builder1.build());
110
111         return builder.build();
112     }
113
114     private Class<? extends Transport> getTransportForString(String transport) {
115         switch(transport) {
116         case "ssh" : return NetconfSsh.class;
117         case "tcp" : return NetconfTcp.class;
118         default: throw new IllegalArgumentException("Unknown transport type " + transport);
119         }
120     }
121
122     private String formatDateTime(Date loginTime) {
123         SimpleDateFormat dateFormat = new SimpleDateFormat(ISO_DATE_FORMAT);
124         return dateFormat.format(loginTime);
125     }
126
127     @Override
128     protected NetconfServerSession thisInstance() {
129         return this;
130     }
131
132     @Override
133     protected void addExiHandlers(NetconfEXICodec exiCodec) {
134         replaceMessageDecoder(new NetconfEXIToMessageDecoder(exiCodec));
135         replaceMessageEncoderAfterNextMessage(new NetconfMessageToEXIEncoder(exiCodec));
136     }
137
138     @Override
139     public void stopExiCommunication() {
140         replaceMessageDecoder(new NetconfXMLToMessageDecoder());
141         replaceMessageEncoderAfterNextMessage(new NetconfMessageToXMLEncoder());
142     }
143 }