X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Ftools%2Fnetconf-cli%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fcli%2Fcommands%2FCommandDispatcher.java;fp=opendaylight%2Fnetconf%2Ftools%2Fnetconf-cli%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fcli%2Fcommands%2FCommandDispatcher.java;h=f1b14eabda70f365c2c6b8902e5295877f84fa5f;hb=23fe9ca678ada6263fec5dd996f4025e4a32fcf5;hp=0000000000000000000000000000000000000000;hpb=071a641d7c12c0e6112d5ce0afe806b54f116ed2;p=controller.git diff --git a/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java new file mode 100644 index 0000000000..f1b14eabda --- /dev/null +++ b/opendaylight/netconf/tools/netconf-cli/src/main/java/org/opendaylight/controller/netconf/cli/commands/CommandDispatcher.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.netconf.cli.commands; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import java.io.InputStream; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.opendaylight.controller.md.sal.dom.api.DOMRpcService; +import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionHandler; +import org.opendaylight.controller.netconf.cli.NetconfDeviceConnectionManager; +import org.opendaylight.controller.netconf.cli.commands.local.Close; +import org.opendaylight.controller.netconf.cli.commands.local.Connect; +import org.opendaylight.controller.netconf.cli.commands.local.Disconnect; +import org.opendaylight.controller.netconf.cli.commands.local.Help; +import org.opendaylight.controller.netconf.cli.commands.remote.RemoteCommand; +import org.opendaylight.controller.netconf.cli.io.IOUtil; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; + +/** + * The registry of available commands local + remote. Created from schema contexts. + */ +public class CommandDispatcher { + + // TODO extract interface + + private final Map localCommands = Maps.newHashMap(); + private final Map nameToQNameLocal = Maps.newHashMap(); + + private final Map remoteCommands = Maps.newHashMap(); + private final Map nameToQNameRemote = Maps.newHashMap(); + + public synchronized Map getCommands() { + return Collections.unmodifiableMap(mergeCommands()); + } + + private Map mergeCommands() { + // TODO cache this merged map + return mergeMaps(remoteCommands, localCommands); + } + + private Map mergeCommandIds() { + // TODO cache this merged map + return mergeMaps(nameToQNameRemote, nameToQNameLocal); + } + + private Map mergeMaps(final Map remoteMap, final Map localMap) { + final Map mergedCommands = Maps.newHashMap(); + mergedCommands.putAll(remoteMap); + mergedCommands.putAll(localMap); + return mergedCommands; + } + + public synchronized Set getCommandIds() { + return mergeCommandIds().keySet(); + } + + public synchronized Set getRemoteCommandIds() { + return nameToQNameRemote.keySet(); + } + + public synchronized Optional getCommand(final String nameWithModule) { + final QName commandQName = mergeCommandIds().get(nameWithModule); + final Map qNameCommandMap = mergeCommands(); + if(commandQName == null || qNameCommandMap.containsKey(commandQName) == false) { + return Optional.absent(); + } + + return Optional.of(qNameCommandMap.get(commandQName)); + } + + public synchronized Optional getCommand(final QName qName) { + return Optional.fromNullable(mergeCommands().get(qName)); + } + + private static Optional getCommand(final Map commandNameMap, final Map commands, final String nameWithModule) { + final QName qName = commandNameMap.get(nameWithModule); + if(qName == null) + return Optional.absent(); + + final Command command = commands.get(qName); + if(command == null) { + return Optional.absent(); + } + + return Optional.of(command); + } + + public static final Collection BASE_NETCONF_SCHEMA_PATHS = Lists.newArrayList("/schema/remote/ietf-netconf.yang", + "/schema/common/netconf-cli-ext.yang", "/schema/common/ietf-inet-types.yang"); + + public synchronized void addRemoteCommands(final DOMRpcService rpcService, final SchemaContext remoteSchema) { + this.addRemoteCommands(rpcService, remoteSchema, parseSchema(BASE_NETCONF_SCHEMA_PATHS)); + } + + public synchronized void addRemoteCommands(final DOMRpcService rpcService, final SchemaContext remoteSchema, final SchemaContext baseNetconfSchema) { + for (final SchemaContext context : Lists.newArrayList(remoteSchema, baseNetconfSchema)) { + for (final Module module : context.getModules()) { + for (final RpcDefinition rpcDefinition : module.getRpcs()) { + final Command command = RemoteCommand.fromRpc(rpcDefinition, rpcService); + remoteCommands.put(rpcDefinition.getQName(), command); + nameToQNameRemote.put(getCommandName(rpcDefinition, module), rpcDefinition.getQName()); + } + } + } + } + + public synchronized void removeRemoteCommands() { + remoteCommands.clear(); + nameToQNameRemote.clear(); + } + + public static final Collection LOCAL_SCHEMA_PATHS = Lists.newArrayList("/schema/local/netconf-cli.yang", "/schema/common/netconf-cli-ext.yang", + "/schema/common/ietf-inet-types.yang"); + + public synchronized void addLocalCommands(final NetconfDeviceConnectionManager connectionManager, final SchemaContext localSchema, final Integer connectionTimeout) { + for (final Module module : localSchema.getModules()) { + for (final RpcDefinition rpcDefinition : module.getRpcs()) { + + // FIXME make local commands extensible + // e.g. by yang extension defining java class to be instantiated + // problem is with command specific resources + // e.g. Help would need command registry + final Command localCommand; + if (rpcDefinition.getQName().equals(CommandConstants.HELP_QNAME)) { + localCommand = Help.create(rpcDefinition, this); + } else if (rpcDefinition.getQName().equals(CommandConstants.CLOSE_QNAME)) { + localCommand = Close.create(rpcDefinition); + } else if (rpcDefinition.getQName().equals(CommandConstants.CONNECT_QNAME)) { + localCommand = Connect.create(rpcDefinition, connectionManager, connectionTimeout); + } else if (rpcDefinition.getQName().equals(CommandConstants.DISCONNECT_QNAME)) { + localCommand = Disconnect.create(rpcDefinition, connectionManager); + } else { + throw new IllegalStateException("No command implementation available for local command: " + rpcDefinition.getQName()); + } + + localCommands.put(localCommand.getCommandId(), localCommand); + nameToQNameLocal.put(getCommandName(rpcDefinition, module), localCommand.getCommandId()); + } + } + } + + private static String getCommandName(final RpcDefinition rpcDefinition, final Module module) { + return IOUtil.qNameToKeyString(rpcDefinition.getQName(), module.getName()); + } + + public static SchemaContext parseSchema(final Collection yangPath) { + final YangParserImpl yangParserImpl = new YangParserImpl(); + // TODO change deprecated method + final Set modules = yangParserImpl.parseYangModelsFromStreams(loadYangs(yangPath)); + return yangParserImpl.resolveSchemaContext(modules); + } + + private static List loadYangs(final Collection yangPaths) { + + return Lists.newArrayList(Collections2.transform(Lists.newArrayList(yangPaths), + new Function() { + @Override + public InputStream apply(final String input) { + final InputStream resourceAsStream = NetconfDeviceConnectionHandler.class.getResourceAsStream(input); + Preconditions.checkNotNull(resourceAsStream, "File %s was null", input); + return resourceAsStream; + } + })); + } +}