*/
package org.opendaylight.controller.sal.connect.netconf.util;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import javax.annotation.Nullable;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.controller.sal.common.util.RpcErrors;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.Node;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
public class NetconfMessageTransformUtil {
private NetconfMessageTransformUtil() {
}
- public static final QName IETF_NETCONF_MONITORING = QName.create(
- "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
+ public static final QName IETF_NETCONF_MONITORING = QName.create("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0");
public static QName NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf");
public static QName NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
public static QName NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
public static QName NETCONF_ERROR_OPTION_QNAME = QName.create(NETCONF_QNAME, "error-option");
public static QName NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
- static List<Node<?>> RUNNING = Collections.<Node<?>> singletonList(new SimpleNodeTOImpl<>(NETCONF_RUNNING_QNAME,
- null, null));
+ static List<Node<?>> RUNNING = Collections.<Node<?>> singletonList(new SimpleNodeTOImpl<>(NETCONF_RUNNING_QNAME, null, null));
public static QName NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
public static CompositeNode CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME, null, RUNNING);
public static QName NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate");
public static QName NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config");
public static QName NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit");
public static QName NETCONF_OPERATION_QNAME = QName.create(NETCONF_QNAME, "operation");
+ public static QName NETCONF_DEFAULT_OPERATION_QNAME = QName.create(NETCONF_OPERATION_QNAME, "default-operation");
public static QName NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config");
public static QName NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
public static QName NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
public static Node<?> toFilterStructure(final InstanceIdentifier identifier) {
Node<?> previous = null;
- if (identifier.getPath().isEmpty()) {
+ if (Iterables.isEmpty(identifier.getPathArguments())) {
return null;
}
return new CompositeNodeTOImpl(argument.getNodeType(), null, list);
}
- public static void checkValidReply(final NetconfMessage input, final NetconfMessage output) {
+ public static void checkValidReply(final NetconfMessage input, final NetconfMessage output)
+ throws NetconfDocumentedException {
final String inputMsgId = input.getDocument().getDocumentElement().getAttribute("message-id");
final String outputMsgId = output.getDocument().getDocumentElement().getAttribute("message-id");
if(inputMsgId.equals(outputMsgId) == false) {
- final String requestXml = XmlUtil.toString(input.getDocument());
- final String responseXml = XmlUtil.toString(output.getDocument());
- throw new IllegalStateException(String.format("Rpc request and reply message IDs must be same. Request: %s, response: %s", requestXml, responseXml));
+ Map<String,String> errorInfo = ImmutableMap.<String,String>builder()
+ .put( "actual-message-id", outputMsgId )
+ .put( "expected-message-id", inputMsgId )
+ .build();
+
+ throw new NetconfDocumentedException( "Response message contained unknown \"message-id\"",
+ null, NetconfDocumentedException.ErrorType.protocol,
+ NetconfDocumentedException.ErrorTag.bad_attribute,
+ NetconfDocumentedException.ErrorSeverity.error, errorInfo );
}
}
public static void checkSuccessReply(final NetconfMessage output) throws NetconfDocumentedException {
if(NetconfMessageUtil.isErrorMessage(output)) {
- throw new IllegalStateException(String.format("Response contains error: %s", XmlUtil.toString(output.getDocument())));
+ throw NetconfDocumentedException.fromXMLDocument( output.getDocument() );
+ }
+ }
+
+ public static RpcError toRpcError( final NetconfDocumentedException ex )
+ {
+ StringBuilder infoBuilder = new StringBuilder();
+ Map<String, String> errorInfo = ex.getErrorInfo();
+ if( errorInfo != null )
+ {
+ for( Entry<String,String> e: errorInfo.entrySet() ) {
+ infoBuilder.append( '<' ).append( e.getKey() ).append( '>' ).append( e.getValue() )
+ .append( "</" ).append( e.getKey() ).append( '>' );
+
+ }
+ }
+
+ return RpcErrors.getRpcError( null, ex.getErrorTag().getTagValue(), infoBuilder.toString(),
+ toRpcErrorSeverity( ex.getErrorSeverity() ), ex.getLocalizedMessage(),
+ toRpcErrorType( ex.getErrorType() ), ex.getCause() );
+ }
+
+ private static ErrorSeverity toRpcErrorSeverity( final NetconfDocumentedException.ErrorSeverity severity ) {
+ switch( severity ) {
+ case warning:
+ return RpcError.ErrorSeverity.WARNING;
+ default:
+ return RpcError.ErrorSeverity.ERROR;
+ }
+ }
+
+ private static RpcError.ErrorType toRpcErrorType( final NetconfDocumentedException.ErrorType type )
+ {
+ switch( type ) {
+ case protocol:
+ return RpcError.ErrorType.PROTOCOL;
+ case rpc:
+ return RpcError.ErrorType.RPC;
+ case transport:
+ return RpcError.ErrorType.TRANSPORT;
+ default:
+ return RpcError.ErrorType.APPLICATION;
}
}
public static CompositeNode flattenInput(final CompositeNode node) {
final QName inputQName = QName.create(node.getNodeType(), "input");
final CompositeNode input = node.getFirstCompositeByName(inputQName);
- if (input == null)
+ if (input == null) {
return node;
+ }
if (input instanceof CompositeNode) {
final List<Node<?>> nodes = ImmutableList.<Node<?>> builder() //
.addAll(Collections2.filter(node.getValue(), new Predicate<Node<?>>() {
@Override
public boolean apply(@Nullable final Node<?> input) {
- return input.getNodeType() != inputQName;
+ return !inputQName.equals(input.getNodeType());
}
})) //
.build();