--- /dev/null
+/**
+ * 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.openflowplugin.extension.api;
+
+import org.opendaylight.openflowplugin.extension.api.path.AugmentationPath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+/**
+ * convert message from OFJava-API model into MD-SAL model
+ *
+ * @param <F> input message model - OFJava-API
+ * @param <P> represents possible paths in yang schema for augmentations
+ */
+public interface ConvertorMessageFromOFJava<F extends DataContainer, P extends AugmentationPath> {
+
+ /**
+ * @param input
+ * @param path in yang schema where a converted value has to be augmented
+ * @return message converted to MD-SAL and its type
+ */
+ ExperimenterMessageOfChoice convert(F input, P path);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.openflowplugin.extension.api;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+/**
+ * convert message from MD-SAL model into OFJava-API model
+ *
+ * @param <F> input message model - MD-SAL model
+ * @param <T> output message model - OFJava-API
+ */
+public interface ConvertorMessageToOFJava<F extends ExperimenterMessageOfChoice, T extends DataContainer> {
+
+ /**
+ * @param experimenterMessageCase where is vendor's augmentation
+ * @return message converted to OFJava-API
+ */
+ T convert(F experimenterMessageCase);
+}
import org.opendaylight.openflowjava.protocol.api.keys.ActionSerializerKey;
import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey;
+import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
+import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
/**
* registration place for message converters provided by vendor extension
*/
ObjectRegistration<ConvertorActionFromOFJava<Action, ActionPath>> registerActionConvertor(
ActionSerializerKey<?> key, ConvertorActionFromOFJava<Action, ActionPath> convertor);
+
+ /**
+ * @param key consists of: experimenter type, version
+ * @param convertor TO OFJava (suitable for both: symmetric and multipart)
+ * @return closeable registration
+ */
+ ObjectRegistration<ConvertorMessageToOFJava<ExperimenterMessageOfChoice, DataContainer>> registerMessageConvertor(
+ TypeVersionKey<? extends ExperimenterMessageOfChoice> key, ConvertorMessageToOFJava<ExperimenterMessageOfChoice, DataContainer> convertor);
+
+ /**
+ * @param key consists of: experimenter type, version
+ * @param convertor FROM OFJava (suitable for both: symmetric and multipart)
+ * @return closeable registration
+ */
+ ObjectRegistration<ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath>> registerMessageConvertor(
+ MessageTypeKey<?> key,
+ ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath> convertor);
}
--- /dev/null
+/*
+ * Copyright (c) 2015 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.openflowplugin.extension.api.path;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.Extension;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * List of augmentation points available for experimenter symmetric message and multipart message
+ */
+public enum MessagePath implements AugmentationPath {
+
+ /**
+ * <pre>
+ * module: sal-experimenter-message
+ * notifications:
+ * +---n experimenter-message-from-dev
+ * +--ro (experimenter-message-of-choice)?module: sal-flow
+ * </pre>
+ */
+ MESSAGE_NOTIFICATION(null),
+ /**
+ * <pre>
+ * module: sal-experimenter-mp-message
+ * rpcs:
+ * +---x send-experimenter-mp-request
+ * +--ro output
+ * +--ro (experimenter-message-of-choice)?notifications:
+ * </pre>
+ */
+ MPMESSAGE_RPC_OUTPUT(null);
+
+ private final InstanceIdentifier<Extension> iid;
+
+ private MessagePath(InstanceIdentifier<Extension> iid) {
+ this.iid = iid;
+ }
+
+ @Override
+ public final InstanceIdentifier<Extension> getInstanceIdentifier() {
+ return iid;
+ }
+
+}
--- /dev/null
+module openflowplugin-experimenter-types {
+ namespace "urn:opendaylight:openflowplugin:experimenter:types";
+ prefix exp-type;
+
+ revision "2015-10-20" {
+ description "Initial revision of experimenter basic types";
+ }
+
+
+ grouping experimenter-core-message {
+ choice experimenter-message-of-choice {
+ // to be augmented by vendors
+ }
+ }
+}
--- /dev/null
+module sal-experimenter-message {
+ namespace "urn:opendaylight:experimenter-message:service";
+ prefix exp-msg;
+
+ import opendaylight-inventory {prefix inv; revision-date "2013-08-19";}
+ import openflowplugin-experimenter-types {prefix exp-type; revision-date "2015-10-20";}
+
+ description "Openflow experimenter (symmetric) message service and notification.";
+
+ revision "2015-10-20" {
+ description "Initial revision of experimenter message service";
+ }
+
+ grouping experimenter-symmetric-message {
+ description "Experimenter message with node and xid reference included.";
+ uses "inv:node-context-ref";
+ uses exp-type:experimenter-core-message;
+ }
+
+ rpc send-experimenter {
+ description "Send experimenter request to device, expecting reply.";
+ input {
+ uses "inv:node-context-ref";
+ uses exp-type:experimenter-core-message;
+ }
+ }
+
+ notification experimenter-message-from-dev {
+ description "Upon experimenter request message received.";
+ uses experimenter-symmetric-message;
+ }
+
+}
--- /dev/null
+module sal-experimenter-mp-message {
+ namespace "urn:opendaylight:experimenter-mp-message:service";
+ prefix exp-mp-msg;
+
+ import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
+ import openflowplugin-experimenter-types {prefix exp-type;revision-date "2015-10-20";}
+
+ description "Openflow multipart experimenter message service.";
+
+ revision "2015-10-20" {
+ description "Initial revision of experimenter multipart message service";
+ }
+
+ rpc send-experimenter-mp-request {
+ description "Send experimenter multipart request to device, expecting reply.";
+ input {
+ uses "inv:node-context-ref";
+ uses exp-type:experimenter-core-message;
+ }
+ output {
+ uses exp-type:experimenter-core-message;
+ }
+ }
+}
import org.opendaylight.openflowplugin.extension.api.ConvertorActionFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
import org.opendaylight.openflowplugin.extension.api.path.AugmentationPath;
import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
+import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
import org.opendaylight.openflowplugin.openflow.md.core.extension.RegistrationCloser.RegistrationCloserActionFromOFJava;
import org.opendaylight.openflowplugin.openflow.md.core.extension.RegistrationCloser.RegistrationCloserActionToOFJava;
import org.opendaylight.openflowplugin.openflow.md.core.extension.RegistrationCloser.RegistrationCloserFromOFJava;
+import org.opendaylight.openflowplugin.openflow.md.core.extension.RegistrationCloser.RegistrationCloserMessageFromOFJava;
+import org.opendaylight.openflowplugin.openflow.md.core.extension.RegistrationCloser.RegistrationCloserMessageToOFJava;
import org.opendaylight.openflowplugin.openflow.md.core.extension.RegistrationCloser.RegistrationCloserToOFJava;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
import org.opendaylight.yangtools.yang.binding.DataContainer;
private final Map<ConverterExtensionKey<?>, ConvertorToOFJava<?>> registryToOFJAva;
private final Map<TypeVersionKey<? extends Action>, ConvertorActionToOFJava<? extends Action, ? extends DataContainer>> registryActionToOFJAva;
private final Map<MessageTypeKey<?>, ConvertorActionFromOFJava<?, ?>> registryActionFromOFJAva;
+ private final Map<TypeVersionKey<?>, ConvertorMessageToOFJava<ExperimenterMessageOfChoice, DataContainer>> registryMessageToOFJAva;
+ private final Map<MessageTypeKey<?>, ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath>> registryMessageFromOFJAva;
/**
* default ctor
registryToOFJAva = new ConcurrentHashMap<>();
registryActionToOFJAva = new ConcurrentHashMap<>();
registryActionFromOFJAva = new ConcurrentHashMap<>();
+ registryMessageToOFJAva = new ConcurrentHashMap<>();
+ registryMessageFromOFJAva = new ConcurrentHashMap<>();
}
/**
return janitor;
}
+ /**
+ * @param key
+ * @param extConvertor
+ * @return
+ */
+ private <TO extends DataContainer> RegistrationCloserMessageToOFJava<TO> hireMessageJanitor(
+ final TypeVersionKey<? extends ExperimenterMessageOfChoice> key,
+ final ConvertorMessageToOFJava<ExperimenterMessageOfChoice, TO> extConvertor) {
+ RegistrationCloserMessageToOFJava<TO> janitor = new RegistrationCloserMessageToOFJava<>();
+ janitor.setConverter(extConvertor);
+ janitor.setKey(key);
+ janitor.setRegistrator(this);
+ return janitor;
+ }
+
+ /**
+ * @param key
+ * @param extConvertor
+ * @return
+ */
+ private <FROM extends DataContainer, PATH extends AugmentationPath, KEY extends MessageTypeKey<?>>
+ RegistrationCloserMessageFromOFJava<FROM, PATH> hireMessageJanitor(
+ final KEY key, final ConvertorMessageFromOFJava<FROM, PATH> extConvertor) {
+ RegistrationCloserMessageFromOFJava<FROM, PATH> janitor = new RegistrationCloserMessageFromOFJava<>();
+ janitor.setConverter(extConvertor);
+ janitor.setKey(key);
+ janitor.setRegistrator(this);
+ return janitor;
+ }
+
/**
* cancel registration of given converter
*
}
}
+ /**
+ * cancel registration of given converter
+ *
+ * @param key
+ * @param converter
+ */
+ public void unregister(final MessageTypeKey<?> key, final ConvertorMessageFromOFJava<?, ?> converter) {
+ ConvertorMessageFromOFJava<?, ?> registeredConverter = registryMessageFromOFJAva.get(key);
+ if (registeredConverter != null && registeredConverter == converter) {
+ registryMessageFromOFJAva.remove(key);
+ }
+ }
+
+ /**
+ * cancel registration of given converter
+ *
+ * @param key
+ * @param converter
+ */
+ public void unregister(final TypeVersionKey<?> key, final ConvertorMessageToOFJava<?, ?> converter) {
+ ConvertorMessageToOFJava<?, ?> registeredConverter = registryMessageToOFJAva.get(key);
+ if (registeredConverter != null && registeredConverter == converter) {
+ registryMessageToOFJAva.remove(key);
+ }
+ }
+
@SuppressWarnings("unchecked")
@Override
public <FROM extends DataContainer> ConvertorToOFJava<FROM> getConverter(
return hireJanitor(key, convertor);
}
+ @Override
+ public ObjectRegistration<ConvertorMessageToOFJava<ExperimenterMessageOfChoice, DataContainer>> registerMessageConvertor(
+ TypeVersionKey<? extends ExperimenterMessageOfChoice> key, ConvertorMessageToOFJava<ExperimenterMessageOfChoice, DataContainer> convertor) {
+ registryMessageToOFJAva.put(key, convertor);
+ return hireMessageJanitor(key, convertor);
+ }
+
+ @Override
+ public ObjectRegistration<ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath>> registerMessageConvertor(
+ MessageTypeKey<?> key, ConvertorMessageFromOFJava<ExperimenterDataOfChoice, MessagePath> convertor) {
+ registryMessageFromOFJAva.put(key, convertor);
+ return hireMessageJanitor(key, convertor);
+ }
}
/**
* 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
import org.opendaylight.openflowplugin.extension.api.ConvertorActionFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.path.AugmentationPath;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
import org.opendaylight.yangtools.yang.binding.DataContainer;
* @param <CONVERTER> converter instance
*/
public abstract class RegistrationCloser<KEY, CONVERTER> implements ObjectRegistration<CONVERTER> {
-
+
private ExtensionConverterManagerImpl registrator;
private KEY key;
private CONVERTER converter;
-
+
/**
* @param registrator the registrator to set
*/
public CONVERTER getConverter() {
return converter;
}
-
+
@Override
public CONVERTER getInstance() {
return getConverter();
}
-
+
/**
* standalone deregistrator
* @param <TO> target type of wrapped convertor
*/
- public static class RegistrationCloserToOFJava<TO extends DataContainer> extends
+ public static class RegistrationCloserToOFJava<TO extends DataContainer> extends
RegistrationCloser<ConverterExtensionKey<? extends ExtensionKey>, ConvertorToOFJava<TO>> {
-
+
@Override
public void close() throws Exception {
getRegistrator().unregister(getKey(), getConverter());
}
}
-
+
/**
* standalone deregistrator
* @param <FROM> source type of wrapped convertor
* @param <PATH> associated augmentation path
*/
public static class RegistrationCloserFromOFJava<FROM extends DataContainer, PATH extends AugmentationPath> extends RegistrationCloser<MessageTypeKey<?>, ConvertorFromOFJava<FROM, PATH>> {
-
+
@Override
public void close() throws Exception {
getRegistrator().unregister(getKey(), getConverter());
}
}
-
+
/**
* standalone deregistrator
* @param <TO> target type of wrapped convertor
*/
- public static class RegistrationCloserActionToOFJava<TO extends DataContainer> extends
+ public static class RegistrationCloserActionToOFJava<TO extends DataContainer> extends
RegistrationCloser<TypeVersionKey<? extends Action>, ConvertorActionToOFJava<Action, TO>> {
-
+
+ @Override
+ public void close() throws Exception {
+ getRegistrator().unregister(getKey(), getConverter());
+ }
+ }
+
+ /**
+ * standalone deregistrator
+ * @param <FROM> source type of wrapped convertor
+ * @param <PATH> associated augmentation path
+ */
+ public static class RegistrationCloserActionFromOFJava<FROM extends DataContainer, PATH extends AugmentationPath> extends
+ RegistrationCloser<MessageTypeKey<?>, ConvertorActionFromOFJava<FROM, PATH>> {
+
+ @Override
+ public void close() throws Exception {
+ getRegistrator().unregister(getKey(), getConverter());
+ }
+ }
+
+ /**
+ * standalone deregistrator
+ *
+ * @param <TO> target type of wrapped convertor
+ */
+ public static class RegistrationCloserMessageToOFJava<TO extends DataContainer> extends
+ RegistrationCloser<TypeVersionKey<? extends ExperimenterMessageOfChoice>, ConvertorMessageToOFJava<ExperimenterMessageOfChoice, TO>> {
+
@Override
public void close() throws Exception {
getRegistrator().unregister(getKey(), getConverter());
}
}
-
+
/**
* standalone deregistrator
+ *
* @param <FROM> source type of wrapped convertor
* @param <PATH> associated augmentation path
*/
- public static class RegistrationCloserActionFromOFJava<FROM extends DataContainer, PATH extends AugmentationPath> extends RegistrationCloser<MessageTypeKey<?>, ConvertorActionFromOFJava<FROM, PATH>> {
-
+ public static class RegistrationCloserMessageFromOFJava<FROM extends DataContainer, PATH extends AugmentationPath> extends
+ RegistrationCloser<MessageTypeKey<?>, ConvertorMessageFromOFJava<FROM, PATH>> {
+
@Override
public void close() throws Exception {
getRegistrator().unregister(getKey(), getConverter());
}
}
+
+
}