start to dependency inject CRUD implementations (to be completed) 32/70932/4
authorMichael Vorburger <vorburger@redhat.com>
Fri, 13 Apr 2018 20:34:51 +0000 (22:34 +0200)
committerMichael Vorburger <vorburger@redhat.com>
Tue, 17 Apr 2018 17:07:00 +0000 (19:07 +0200)
Change-Id: Ie5d4d12720404666709df98c8870de795fde26fb
Signed-off-by: Michael Vorburger <vorburger@redhat.com>
features/production/odl-neutron-northbound-api/pom.xml
features/production/odl-neutron-service/pom.xml
northbound-api/pom.xml
northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/AbstractNeutronNorthbound.java
northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronNetworksNorthbound.java
northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/NeutronNorthboundRSApplication.java
northbound-api/src/main/java/org/opendaylight/neutron/northbound/api/WebInitializer.java

index c0e120339831595dc9e5519076c9925e98f492c3..a38afed2fbeb55083c0f35c993a28914b4f69c2b 100644 (file)
             <artifactId>northbound-api</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <!-- because the REST API classes @Inject @OsgiService INeutronCRUD dependencies,
+             we do need a dependency to the implementation of those INeutronCRUDs in transcriber;
+             otherwise this feature would not work standalone, and SFT will fail. -->
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>transcriber</artifactId>
+            <version>${project.version}</version>
+        </dependency>
      </dependencies>
 </project>
index b8e11f7db29f5b81830db6127e8abf197ebe72c7..38dde7a5009b8f5698c32eac16e5b048b70e8ab6 100644 (file)
             <type>xml</type>
             <classifier>features</classifier>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>transcriber</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>model</artifactId>
index e0e70dde3687807317a7a6f10a53c7f6d3e88e40..cd693938387943ab2ea833a094c6ca5bdfcb1e99 100644 (file)
@@ -56,6 +56,8 @@
     </dependency>
     <dependency>
       <groupId>org.osgi</groupId>
+      <!-- TODO Remove this when AbstractNeutronNorthbound does not need
+           to use bundleContext.getServiceReferences() anymore... -->
       <artifactId>org.osgi.core</artifactId>
     </dependency>
     <dependency>
       <artifactId>javax.inject</artifactId>
       <optional>true</optional>
     </dependency>
+    <dependency>
+     <groupId>org.ops4j.pax.cdi</groupId>
+     <artifactId>pax-cdi-api</artifactId>
+     <optional>true</optional>
+   </dependency>
     <dependency>
       <groupId>org.opendaylight.aaa.web</groupId>
       <artifactId>web-api</artifactId>
index cfffca3fa38ad9e49978d2038e4e277cd97edafa..cb1f0cd0f83324ac1e841a2448c0d66f4085b647 100644 (file)
@@ -14,6 +14,7 @@ import java.lang.reflect.ParameterizedType;
 import java.net.HttpURLConnection;
 import java.util.Collection;
 import java.util.List;
+import java.util.Objects;
 import javax.ws.rs.core.Response;
 import org.opendaylight.neutron.spi.INeutronCRUD;
 import org.opendaylight.neutron.spi.INeutronObject;
@@ -42,6 +43,23 @@ public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, R e
     private static final String INTERFACE_NAME_BASE = " CRUD Interface";
     private static final String UUID_NO_EXIST_BASE = " UUID does not exist.";
 
+    private final I neutronCRUD;
+
+    /**
+     * Default constructor.
+     *
+     * @deprecated Replace usage of this method with direct dependency injection,
+     *             see NeutronNetworksNorthbound for how-to.  This will shortly be removed.
+     */
+    @Deprecated
+    protected AbstractNeutronNorthbound() {
+        this.neutronCRUD = null;
+    }
+
+    protected AbstractNeutronNorthbound(I neutronCRUD) {
+        this.neutronCRUD = Objects.requireNonNull(neutronCRUD, "neutronCRUD");
+    }
+
     protected final String serviceUnavailable() {
         return getResourceName() + INTERFACE_NAME_BASE + RestMessages.SERVICEUNAVAILABLE.toString();
     }
@@ -78,6 +96,11 @@ public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, R e
     }
 
     protected I getNeutronCRUD() {
+        // TODO remove null check and everything below when the @deprecated default constructor is removed...
+        if (this.neutronCRUD != null) {
+            return this.neutronCRUD;
+        }
+
         // cls = I.class
         Class<I> cls = getActualTypeArgument(NEUTRON_CRUD_TYPE_INDEX);
         I neutronCrud = fetchINeutronCRUD(cls, (Object) this);
@@ -104,8 +127,8 @@ public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, R e
     protected Response show(String uuid,
             // return fields
             List<String> fields) {
-        I neutronCRUD = getNeutronCRUD();
-        T ans = neutronCRUD.get(uuid);
+        I gotNeutronCRUD = getNeutronCRUD(); // TODO remove and just use new private neutronCRUD field
+        T ans = gotNeutronCRUD.get(uuid);
         if (ans == null) {
             throw new ResourceNotFoundException(uuidNoExist());
         }
@@ -119,19 +142,19 @@ public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, R e
     }
 
     protected Response create(final R input) {
-        I neutronCRUD = getNeutronCRUD();
+        I gotNeutronCRUD = getNeutronCRUD(); // TODO remove and just use new private neutronCRUD field
         if (input.isSingleton()) {
             T singleton = input.getSingleton();
 
             singleton.initDefaults();
-            neutronCRUD.add(singleton);
+            gotNeutronCRUD.add(singleton);
         } else {
             if (input.getBulk() == null) {
                 throw new BadRequestException("Invalid requests");
             }
             for (T test : input.getBulk()) {
                 test.initDefaults();
-                neutronCRUD.add(test);
+                gotNeutronCRUD.add(test);
             }
         }
         return Response.status(HttpURLConnection.HTTP_CREATED).entity(input).build();
@@ -156,12 +179,12 @@ public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, R e
     }
 
     protected Response update(String uuid, final R input) {
-        I neutronCRUD = getNeutronCRUD();
+        I gotNeutronCRUD = getNeutronCRUD(); // TODO remove and just use new private neutronCRUD field
         if (!input.isSingleton()) {
             throw new BadRequestException("Only singleton edit supported");
         }
         T delta = input.getSingleton();
-        T original = neutronCRUD.get(uuid);
+        T original = gotNeutronCRUD.get(uuid);
         if (original == null) {
             throw new ResourceNotFoundException(uuidNoExist());
         }
@@ -172,20 +195,20 @@ public abstract class AbstractNeutronNorthbound<T extends INeutronObject<T>, R e
         /*
          * update the object and return it
          */
-        if (!neutronCRUD.update(uuid, delta)) {
+        if (!gotNeutronCRUD.update(uuid, delta)) {
             throw new ResourceNotFoundException(uuidNoExist());
         }
-        T updated = neutronCRUD.get(uuid);
+        T updated = gotNeutronCRUD.get(uuid);
         return Response.status(HttpURLConnection.HTTP_OK).entity(newNeutronRequest(updated)).build();
     }
 
     protected Response delete(String uuid) {
-        final I neutronCRUD = getNeutronCRUD();
+        final I gotNeutronCRUD = getNeutronCRUD(); // TODO remove and just use new private neutronCRUD field
 
         /*
          * remove it and return 204 status
          */
-        if (!neutronCRUD.remove(uuid)) {
+        if (!gotNeutronCRUD.remove(uuid)) {
             throw new ResourceNotFoundException(uuidNoExist());
         }
 
index 7a7104ab5dd60e19fe6ea9790d774a97fac00d0b..dbc4600ee77bd2a475ccfcc2236af66867160554 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.neutron.northbound.api;
 import java.net.HttpURLConnection;
 import java.util.ArrayList;
 import java.util.List;
+import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.DefaultValue;
@@ -27,18 +29,26 @@ import javax.ws.rs.core.UriInfo;
 import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
 import org.codehaus.enunciate.jaxrs.TypeHint;
+import org.opendaylight.neutron.spi.INeutronCRUD;
 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
 import org.opendaylight.neutron.spi.NeutronNetwork;
+import org.ops4j.pax.cdi.api.OsgiService;
 
 /**
  * Neutron Northbound REST APIs for Network.
  */
+@Singleton
 @Path("/networks")
 public final class NeutronNetworksNorthbound
         extends AbstractNeutronNorthbound<NeutronNetwork, NeutronNetworkRequest, INeutronNetworkCRUD> {
 
     private static final String RESOURCE_NAME = "Network";
 
+    @Inject
+    public NeutronNetworksNorthbound(@OsgiService INeutronNetworkCRUD neutronNetworkCRUD) {
+        super(neutronNetworkCRUD);
+    }
+
     @Context
     UriInfo uriInfo;
 
@@ -78,7 +88,7 @@ public final class NeutronNetworksNorthbound
             @DefaultValue("false") @QueryParam("page_reverse") Boolean pageReverse
     // sorting not supported
     ) {
-        INeutronNetworkCRUD networkInterface = getNeutronCRUD();
+        INeutronCRUD<NeutronNetwork> networkInterface = getNeutronCRUD();
         List<NeutronNetwork> allNetworks = networkInterface.getAll();
         List<NeutronNetwork> ans = new ArrayList<>();
         for (NeutronNetwork network : allNetworks) {
@@ -110,7 +120,6 @@ public final class NeutronNetworksNorthbound
         }
 
         return Response.status(HttpURLConnection.HTTP_OK).entity(new NeutronNetworkRequest(ans)).build();
-
     }
 
     /**
index 0ef16a0ff80caed0fea9bfbf4e073ebe1e11c624..f63e47b132f3f9a025c380127b2ce5a770b235df 100644 (file)
@@ -13,6 +13,8 @@ import com.google.common.collect.ImmutableSet;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.ws.rs.core.Application;
 import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
 
@@ -21,9 +23,17 @@ import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
  * that will be instantiated for JAXRS processing. This is necessary
  * because package scanning in jersey doesn't yet work in OSGi environment.
  */
+@Singleton
 public final class NeutronNorthboundRSApplication extends Application {
     private static final int HASHMAP_SIZE = 3;
 
+    private final NeutronNetworksNorthbound neutronNetworksNorthbound;
+
+    @Inject
+    public NeutronNorthboundRSApplication(NeutronNetworksNorthbound neutronNetworksNorthbound) {
+        this.neutronNetworksNorthbound = neutronNetworksNorthbound;
+    }
+
     @Override
     public Set<Class<?>> getClasses() {
         return emptySet();
@@ -34,7 +44,7 @@ public final class NeutronNorthboundRSApplication extends Application {
         return ImmutableSet.builderWithExpectedSize(32)
                 .add(getMOXyJsonProvider())
                 // Northbound URIs JAX RS Resources:
-                .add(new NeutronNetworksNorthbound())
+                .add(neutronNetworksNorthbound)
                 .add(new NeutronSubnetsNorthbound())
                 .add(new NeutronPortsNorthbound())
                 .add(new NeutronRoutersNorthbound())
index 0d9003e38195b5ede3936cd4382832549efc8576..51e8ad99c891e28533f047f33719ec2ffaf97f7f 100644 (file)
@@ -29,14 +29,14 @@ public class WebInitializer {
     private final WebContextRegistration registraton;
 
     @Inject
-    public WebInitializer(WebServer webServer, WebContextSecurer webContextSecurer) throws ServletException {
+    public WebInitializer(WebServer webServer, WebContextSecurer webContextSecurer, NeutronNorthboundRSApplication app)
+            throws ServletException {
         WebContextBuilder webContextBuilder = WebContext.builder()
             .contextPath("/controller/nb/v2/neutron").supportsSessions(true)
             // TODO confirm through testing that Jersey & Neutron are fine without sessions, and false instead true
 
             .addServlet(ServletDetails.builder()
-                    .servlet(new com.sun.jersey.spi.container.servlet.ServletContainer(
-                            new NeutronNorthboundRSApplication()))
+                    .servlet(new com.sun.jersey.spi.container.servlet.ServletContainer(app))
                     .addUrlPattern("/*").build());
 
         webContextSecurer.requireAuthentication(webContextBuilder, "/*");