2 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.openvpp.jvpp;
19 import static java.util.Objects.requireNonNull;
21 import java.io.IOException;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26 import org.openvpp.jvpp.callback.ControlPingCallback;
27 import org.openvpp.jvpp.callback.JVppCallback;
28 import org.openvpp.jvpp.dto.ControlPingReply;
31 * Default implementation of JVppRegistry.
33 public final class JVppRegistryImpl implements JVppRegistry, ControlPingCallback {
35 private static final Logger LOG = Logger.getLogger(JVppRegistryImpl.class.getName());
37 private final VppJNIConnection connection;
38 private final ConcurrentMap<String, JVppCallback> pluginRegistry;
39 private final ConcurrentMap<Integer, ControlPingCallback> pingCalls;
41 public JVppRegistryImpl(final String clientName) throws IOException {
42 connection = new VppJNIConnection(clientName);
44 pluginRegistry = new ConcurrentHashMap<>();
45 pingCalls = new ConcurrentHashMap<>();
49 public VppConnection getConnection() {
54 public void register(final JVpp jvpp, final JVppCallback callback) {
55 requireNonNull(jvpp, "jvpp should not be null");
56 requireNonNull(callback, "Callback should not be null");
57 final String name = jvpp.getClass().getName();
58 if (pluginRegistry.putIfAbsent(name, callback) != null) {
59 throw new IllegalArgumentException(String.format("Callback for plugin %s was already registered", name));
61 jvpp.init(this, callback, connection.getConnectionInfo().queueAddress,
62 connection.getConnectionInfo().clientIndex);
66 public void unregister(final String name) {
67 requireNonNull(name, "Plugin name should not be null");
68 final JVppCallback previous = pluginRegistry.remove(name);
69 assertPluginWasRegistered(name, previous);
73 public JVppCallback get(final String name) {
74 requireNonNull(name, "Plugin name should not be null");
75 JVppCallback value = pluginRegistry.get(name);
76 assertPluginWasRegistered(name, value);
80 private native int controlPing0() throws VppInvocationException;
83 public int controlPing(final Class<? extends JVpp> clazz) throws VppInvocationException {
84 connection.checkActive();
85 final String name = clazz.getName();
87 final ControlPingCallback callback = (ControlPingCallback) pluginRegistry.get(clazz.getName());
88 assertPluginWasRegistered(name, callback);
90 int context = controlPing0();
92 throw new VppInvocationException("controlPing", context);
95 pingCalls.put(context, callback);
101 public void onControlPingReply(final ControlPingReply reply) {
102 final ControlPingCallback callback = pingCalls.get(reply.context);
103 if (callback == null) {
104 LOG.log(Level.WARNING, "No callback was registered for reply id={0} ", reply.context);
107 // pass the reply to the callback registered by the ping caller
108 callback.onControlPingReply(reply);
112 public void onError(final VppCallbackException ex) {
113 final int ctxId = ex.getCtxId();
114 final ControlPingCallback callback = pingCalls.get(ctxId);
115 if (callback == null) {
116 LOG.log(Level.WARNING, "No callback was registered for reply id={0} ", ctxId);
119 // pass the error to the callback registered by the ping caller
120 callback.onError(ex);
123 private static void assertPluginWasRegistered(final String name, final JVppCallback value) {
125 throw new IllegalArgumentException(String.format("Callback for plugin %s is not registered", name));
130 public void close() throws Exception {