Move the IntentSynchronizer out of the routing app into its own app

Change-Id: I05e84bce3853ea995b9921b96a2e6a3e8eddb689
diff --git a/apps/castor/BUCK b/apps/castor/BUCK
index 1e2cd89..890b291 100644
--- a/apps/castor/BUCK
+++ b/apps/castor/BUCK
@@ -7,6 +7,7 @@
   '//core/store/serializers:onos-core-serializers',
   '//incubator/api:onos-incubator-api',
   '//apps/routing-api:onos-apps-routing-api',
+  '//apps/intentsync:onos-apps-intentsync',
 ]
 
 BUNDLES = [
@@ -37,4 +38,5 @@
   url = 'http://onosproject.org',
   included_bundles = BUNDLES,
   description = 'Castor application',
-)
\ No newline at end of file
+  required_apps = [ 'org.onosproject.intentsynchronizer' ],
+)
diff --git a/apps/castor/src/main/java/org/onosproject/castor/Castor.java b/apps/castor/src/main/java/org/onosproject/castor/Castor.java
index b604b77..7b2f210 100644
--- a/apps/castor/src/main/java/org/onosproject/castor/Castor.java
+++ b/apps/castor/src/main/java/org/onosproject/castor/Castor.java
@@ -23,7 +23,7 @@
 import org.onosproject.app.ApplicationService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.slf4j.Logger;
 
 import static org.slf4j.LoggerFactory.getLogger;
diff --git a/apps/castor/src/main/java/org/onosproject/castor/ConnectivityManager.java b/apps/castor/src/main/java/org/onosproject/castor/ConnectivityManager.java
index bd55d0d..57943fa 100644
--- a/apps/castor/src/main/java/org/onosproject/castor/ConnectivityManager.java
+++ b/apps/castor/src/main/java/org/onosproject/castor/ConnectivityManager.java
@@ -37,7 +37,7 @@
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
 import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/apps/intentsync/BUCK b/apps/intentsync/BUCK
new file mode 100644
index 0000000..685cd74
--- /dev/null
+++ b/apps/intentsync/BUCK
@@ -0,0 +1,22 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:org.apache.karaf.shell.console',
+    '//cli:onos-cli'
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
+
+onos_app (
+  app_name = 'org.onosproject.intentsynchronizer',
+  title = 'Intent Synchronizer',
+  category = 'Utility',
+  url = 'http://onosproject.org',
+  description = 'Synchronizes intents to the intent framework from a single instance',
+)
diff --git a/apps/intentsync/pom.xml b/apps/intentsync/pom.xml
new file mode 100644
index 0000000..895504e
--- /dev/null
+++ b/apps/intentsync/pom.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onos-apps</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>onos-apps-intentsync</artifactId>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <onos.app.name>org.onosproject.intentsynchronizer</onos.app.name>
+        <onos.app.title>Intent Synchronizer</onos.app.title>
+        <onos.app.category>Utility</onos.app.category>
+        <onos.app.url>http://onosproject.org</onos.app.url>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-cli</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.console</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <scope>test</scope>
+            <classifier>tests</classifier>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationAdminService.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationAdminService.java
similarity index 91%
rename from apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationAdminService.java
rename to apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationAdminService.java
index f868248..5d42046 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationAdminService.java
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationAdminService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.routing;
+package org.onosproject.intentsync;
 
 /**
  * Administrative APIs for managing intent synchronization.
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationService.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationService.java
similarity index 82%
rename from apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationService.java
rename to apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationService.java
index 8f97264..e027d69 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationService.java
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizationService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.routing;
+package org.onosproject.intentsync;
 
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.intent.Intent;
@@ -23,6 +23,12 @@
  * Submits and withdraws intents to the IntentService from a single point in
  * the cluster at any one time. The provided intents will be synchronized with
  * the IntentService on leadership change.
+ * <p>
+ * This is a sample utility and not part of the core ONOS API. This means it is
+ * subject to change or to be removed. It is recommended to consider using one
+ * of the built-in ONOS distributed primitives such as the
+ * {@link org.onosproject.store.service.WorkQueue} instead of using this.
+ * </p>
  */
 public interface IntentSynchronizationService {
 
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/IntentSynchronizer.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizer.java
similarity index 97%
rename from apps/routing/src/main/java/org/onosproject/routing/impl/IntentSynchronizer.java
rename to apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizer.java
index 3b47256..def8172 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/IntentSynchronizer.java
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/IntentSynchronizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.routing.impl;
+package org.onosproject.intentsync;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -34,8 +34,6 @@
 import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.intent.IntentUtils;
 import org.onosproject.net.intent.Key;
-import org.onosproject.routing.IntentSynchronizationAdminService;
-import org.onosproject.routing.IntentSynchronizationService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,7 +52,7 @@
  * Synchronizes intents between an in-memory intent store and the IntentService.
  */
 @Service
-@Component(immediate = false)
+@Component(immediate = true)
 public class IntentSynchronizer implements IntentSynchronizationService,
         IntentSynchronizationAdminService {
 
diff --git a/apps/routing/src/main/java/org/onosproject/routing/cli/PrimaryChangeCommand.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/PrimaryChangeCommand.java
similarity index 82%
rename from apps/routing/src/main/java/org/onosproject/routing/cli/PrimaryChangeCommand.java
rename to apps/intentsync/src/main/java/org/onosproject/intentsync/cli/PrimaryChangeCommand.java
index e9076c1..16898b2 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/cli/PrimaryChangeCommand.java
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/PrimaryChangeCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,12 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.routing.cli;
+package org.onosproject.intentsync.cli;
 
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.routing.IntentSynchronizationAdminService;
+import org.onosproject.intentsync.IntentSynchronizationAdminService;
 
 /**
  * Command to change whether this instance's intent synchronizer is primary.
@@ -34,7 +34,7 @@
 
     @Override
     protected void execute() {
-        get(IntentSynchronizationAdminService.class).modifyPrimary(isPrimary);
+        AbstractShellCommand.get(IntentSynchronizationAdminService.class).modifyPrimary(isPrimary);
     }
 
 }
diff --git a/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/package-info.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/package-info.java
new file mode 100644
index 0000000..53d4b7e
--- /dev/null
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/cli/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Intent synchronizer CLI.
+ */
+package org.onosproject.intentsync.cli;
diff --git a/apps/intentsync/src/main/java/org/onosproject/intentsync/package-info.java b/apps/intentsync/src/main/java/org/onosproject/intentsync/package-info.java
new file mode 100644
index 0000000..5215e6f
--- /dev/null
+++ b/apps/intentsync/src/main/java/org/onosproject/intentsync/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Intent synchronizer.
+ */
+package org.onosproject.intentsync;
diff --git a/apps/intentsync/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/intentsync/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..b100dae
--- /dev/null
+++ b/apps/intentsync/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+  <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+    <command>
+      <action class="org.onosproject.intentsync.cli.PrimaryChangeCommand"/>
+    </command>
+  </command-bundle>
+</blueprint>
diff --git a/apps/routing/src/test/java/org/onosproject/routing/impl/IntentSynchronizerTest.java b/apps/intentsync/src/main/test/org/onosproject/intentsync/IntentSynchronizerTest.java
similarity index 90%
rename from apps/routing/src/test/java/org/onosproject/routing/impl/IntentSynchronizerTest.java
rename to apps/intentsync/src/main/test/org/onosproject/intentsync/IntentSynchronizerTest.java
index 4b7110a..860dec8 100644
--- a/apps/routing/src/test/java/org/onosproject/routing/impl/IntentSynchronizerTest.java
+++ b/apps/intentsync/src/main/test/org/onosproject/intentsync/IntentSynchronizerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-present Open Networking Laboratory
+ * Copyright 2017-present Open Networking Laboratory
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,9 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.routing.impl;
+
+package org.onosproject.intentsync;
 
 import com.google.common.util.concurrent.MoreExecutors;
+import org.easymock.EasyMock;
 import org.junit.Before;
 import org.junit.Test;
 import org.onlab.packet.Ethernet;
@@ -50,12 +52,6 @@
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reset;
-import static org.easymock.EasyMock.verify;
-
 /**
  * This class tests the intent synchronization function in the
  * IntentSynchronizer class.
@@ -95,7 +91,7 @@
 
         setUpConnectPoints();
 
-        intentService = createMock(IntentService.class);
+        intentService = EasyMock.createMock(IntentService.class);
 
         intentSynchronizer = new TestIntentSynchronizer();
 
@@ -157,21 +153,21 @@
         // Set up expectation
         Set<Intent> intents = new HashSet<>();
         intents.add(intent1);
-        expect(intentService.getIntentState(intent1.key()))
+        EasyMock.expect(intentService.getIntentState(intent1.key()))
                 .andReturn(IntentState.INSTALLED).anyTimes();
         intents.add(intent2);
-        expect(intentService.getIntentState(intent2.key()))
+        EasyMock.expect(intentService.getIntentState(intent2.key()))
                 .andReturn(IntentState.INSTALLED).anyTimes();
         intents.add(intent4);
-        expect(intentService.getIntentState(intent4.key()))
+        EasyMock.expect(intentService.getIntentState(intent4.key()))
                 .andReturn(IntentState.INSTALLED).anyTimes();
         intents.add(intent5);
-        expect(intentService.getIntentState(intent5.key()))
+        EasyMock.expect(intentService.getIntentState(intent5.key()))
                 .andReturn(IntentState.INSTALLED).anyTimes();
         intents.add(intent7);
-        expect(intentService.getIntentState(intent7.key()))
+        EasyMock.expect(intentService.getIntentState(intent7.key()))
                 .andReturn(IntentState.WITHDRAWING).anyTimes();
-        expect(intentService.getIntents()).andReturn(intents).anyTimes();
+        EasyMock.expect(intentService.getIntents()).andReturn(intents).anyTimes();
 
         // These are the operations that should be done to the intentService
         // during synchronization
@@ -180,7 +176,7 @@
         intentService.submit(intent4Update);
         intentService.submit(intent6);
         intentService.submit(intent7);
-        replay(intentService);
+        EasyMock.replay(intentService);
 
         // Start the test
 
@@ -202,7 +198,7 @@
         // recorded based on the earlier user input.
         intentSynchronizer.modifyPrimary(true);
 
-        verify(intentService);
+        EasyMock.verify(intentService);
     }
 
     /**
@@ -216,9 +212,9 @@
 
         // Set up expectations
         intentService.submit(intent);
-        expect(intentService.getIntents()).andReturn(Collections.emptyList())
+        EasyMock.expect(intentService.getIntents()).andReturn(Collections.emptyList())
                 .anyTimes();
-        replay(intentService);
+        EasyMock.replay(intentService);
 
         // Give the intent synchronizer leadership so it will submit intents
         // to the intent service
@@ -227,19 +223,19 @@
         // Test the submit
         intentSynchronizer.submit(intent);
 
-        verify(intentService);
+        EasyMock.verify(intentService);
 
         // Now we'll remove leadership from the intent synchronizer and verify
         // that it does not submit any intents to the intent service when we
         // call the submit API
-        reset(intentService);
-        replay(intentService);
+        EasyMock.reset(intentService);
+        EasyMock.replay(intentService);
 
         intentSynchronizer.modifyPrimary(false);
 
         intentSynchronizer.submit(intent);
 
-        verify(intentService);
+        EasyMock.verify(intentService);
     }
 
     /**
@@ -254,9 +250,9 @@
         // Submit an intent first so we can withdraw it later
         intentService.submit(intent);
         intentService.withdraw(intent);
-        expect(intentService.getIntents()).andReturn(Collections.emptyList())
+        EasyMock.expect(intentService.getIntents()).andReturn(Collections.emptyList())
                 .anyTimes();
-        replay(intentService);
+        EasyMock.replay(intentService);
 
         // Give the intent synchronizer leadership so it will submit intents
         // to the intent service
@@ -266,20 +262,20 @@
         intentSynchronizer.submit(intent);
         intentSynchronizer.withdraw(intent);
 
-        verify(intentService);
+        EasyMock.verify(intentService);
 
         // Now we'll remove leadership from the intent synchronizer and verify
         // that it does not withdraw any intents to the intent service when we
         // call the withdraw API
-        reset(intentService);
-        replay(intentService);
+        EasyMock.reset(intentService);
+        EasyMock.replay(intentService);
 
         intentSynchronizer.modifyPrimary(false);
 
         intentSynchronizer.submit(intent);
         intentSynchronizer.withdraw(intent);
 
-        verify(intentService);
+        EasyMock.verify(intentService);
     }
 
     /**
diff --git a/apps/pom.xml b/apps/pom.xml
index 710838d..25d3313 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -86,6 +86,7 @@
         <module>config</module>
         <module>restconf</module>
         <module>ofagent</module>
+        <module>intentsync</module>
     </modules>
 
     <properties>
diff --git a/apps/reactive-routing/BUCK b/apps/reactive-routing/BUCK
index 81feab9..2bb6c6e 100644
--- a/apps/reactive-routing/BUCK
+++ b/apps/reactive-routing/BUCK
@@ -2,6 +2,7 @@
     '//lib:CORE_DEPS',
     '//incubator/api:onos-incubator-api',
     '//apps/routing-api:onos-apps-routing-api',
+    '//apps/intentsync:onos-apps-intentsync',
 ]
 
 osgi_jar (
@@ -13,4 +14,5 @@
     category = 'Traffic Steering',
     url = 'http://onosproject.org',
     description = 'SDN-IP reactive routing application.',
+    required_apps = [ 'org.onosproject.intentsynchronizer' ],
 )
diff --git a/apps/reactive-routing/pom.xml b/apps/reactive-routing/pom.xml
index 83d631b..a599fae 100644
--- a/apps/reactive-routing/pom.xml
+++ b/apps/reactive-routing/pom.xml
@@ -50,6 +50,12 @@
             <artifactId>onos-app-routing</artifactId>
             <version>${project.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-apps-intentsync</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 
-</project>
\ No newline at end of file
+</project>
diff --git a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java
index e3d4d73..e57d9a5 100644
--- a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java
+++ b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java
@@ -16,17 +16,8 @@
 
 package org.onosproject.reactive.routing;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Maps;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
 import org.onlab.packet.Ethernet;
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
@@ -35,6 +26,7 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Host;
 import org.onosproject.net.flow.DefaultTrafficSelector;
@@ -47,10 +39,17 @@
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
 import org.onosproject.net.intent.constraint.PartialFailureConstraint;
 import org.onosproject.routing.IntentRequestListener;
-import org.onosproject.routing.IntentSynchronizationService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * FIB component for reactive routing intents.
  */
diff --git a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
index 6b1df94..d596342 100644
--- a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
+++ b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
@@ -49,7 +49,7 @@
 import org.onosproject.net.packet.PacketProcessor;
 import org.onosproject.net.packet.PacketService;
 import org.onosproject.routing.IntentRequestListener;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.routing.config.RoutingConfigurationService;
 import org.slf4j.Logger;
 
diff --git a/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 95bdfcf..44c99f1 100644
--- a/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/apps/routing/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -26,9 +26,6 @@
       <action class="org.onosproject.routing.cli.BgpSpeakersListCommand"/>
     </command>
     <command>
-      <action class="org.onosproject.routing.cli.PrimaryChangeCommand"/>
-    </command>
-    <command>
       <action class="org.onosproject.routing.cli.AddSpeakerCommand"/>
     </command>
     <command>
diff --git a/apps/sdnip/BUCK b/apps/sdnip/BUCK
index 2a3166f..e91ada3 100644
--- a/apps/sdnip/BUCK
+++ b/apps/sdnip/BUCK
@@ -2,6 +2,7 @@
     '//lib:CORE_DEPS',
     '//incubator/api:onos-incubator-api',
     '//apps/routing-api:onos-apps-routing-api',
+    '//apps/intentsync:onos-apps-intentsync',
     '//lib:org.apache.karaf.shell.console',
     '//cli:onos-cli'
 ]
@@ -29,4 +30,5 @@
   url = 'http://onosproject.org',
   included_bundles = BUNDLES,
   description = 'SDN-IP peering application',
+  required_apps = [ 'org.onosproject.intentsynchronizer' ],
 )
diff --git a/apps/sdnip/app.xml b/apps/sdnip/app.xml
index 4bea73c..c5c2861 100644
--- a/apps/sdnip/app.xml
+++ b/apps/sdnip/app.xml
@@ -17,7 +17,7 @@
 <app name="org.onosproject.sdnip" origin="ON.Lab" version="${project.version}"
      category="Traffic Steering" url="http://onosproject.org" title="SDN-IP App"
      featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
-     features="${project.artifactId}">
+     features="${project.artifactId}" apps="intentsynchronizer">
     <description>${project.description}</description>
     <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
     <artifact>mvn:${project.groupId}/onos-app-routing-api/${project.version}</artifact>
diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index bcbf5ea..e9461ae 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -64,6 +64,12 @@
 
         <dependency>
             <groupId>org.onosproject</groupId>
+            <artifactId>onos-apps-intentsync</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
             <artifactId>onos-app-routing</artifactId>
             <version>${project.version}</version>
         </dependency>
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
index 64046fe..f2e80f1 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
@@ -44,7 +44,7 @@
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.PointToPointIntent;
 import org.onosproject.net.intent.constraint.EncapsulationConstraint;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.routing.RoutingService;
 import org.onosproject.routing.config.BgpConfig;
 import org.onosproject.sdnip.config.SdnIpConfig;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
index 249a2da..4887c72 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
@@ -30,7 +30,7 @@
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.config.basics.SubjectFactories;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.routing.RoutingService;
 import org.onosproject.sdnip.config.SdnIpConfig;
 import org.slf4j.Logger;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
index 1275bd2..94e30d8 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
@@ -54,7 +54,7 @@
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
 import org.onosproject.net.intent.constraint.EncapsulationConstraint;
 import org.onosproject.net.intent.constraint.PartialFailureConstraint;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.sdnip.config.SdnIpConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
index c261f15..9206d45 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
@@ -46,7 +46,7 @@
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.routing.config.BgpConfig;
 import org.onosproject.sdnip.config.SdnIpConfig;
 
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
index 58ff352..0d45475 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
@@ -56,7 +56,7 @@
 import org.onosproject.net.intent.AbstractIntentTest;
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.sdnip.config.SdnIpConfig;
 
 import java.util.Collections;
diff --git a/apps/vpls/BUCK b/apps/vpls/BUCK
index 0cdc7da..471e91c 100644
--- a/apps/vpls/BUCK
+++ b/apps/vpls/BUCK
@@ -6,14 +6,7 @@
     '//cli:onos-cli',
     '//utils/rest:onlab-rest',
     '//incubator/api:onos-incubator-api',
-    '//apps/routing-api:onos-apps-routing-api',
-    '//apps/routing:onos-apps-routing',
-]
-
-BUNDLES = [
-    '//apps/vpls:onos-apps-vpls',
-    '//apps/routing-api:onos-apps-routing-api',
-    '//apps/routing:onos-apps-routing',
+    '//apps/intentsync:onos-apps-intentsync',
 ]
 
 TEST_DEPS = [
@@ -29,6 +22,6 @@
     title = 'VLAN L2 Broadcast Network App',
     category = 'Traffic Steering',
     url = 'http://onosproject.org',
-    included_bundles = BUNDLES,
     description = 'Application to create L2 broadcast network using VLAN.',
+    required_apps = [ 'org.onosproject.intentsynchronizer' ],
 )
diff --git a/apps/vpls/features.xml b/apps/vpls/features.xml
deleted file mode 100644
index 4325d99..0000000
--- a/apps/vpls/features.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!--
-  ~ Copyright 2016-present Open Networking Laboratory
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~     http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
-    <feature name="${project.artifactId}" version="${project.version}"
-             description="${project.description}">
-        <feature>onos-api</feature>
-        <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
-        <bundle>mvn:${project.groupId}/onos-app-routing-api/${project.version}</bundle>
-        <bundle>mvn:${project.groupId}/onos-app-routing/${project.version}</bundle>
-    </feature>
-</features>
diff --git a/apps/vpls/pom.xml b/apps/vpls/pom.xml
index e627c12..89775a5 100644
--- a/apps/vpls/pom.xml
+++ b/apps/vpls/pom.xml
@@ -35,6 +35,7 @@
         <onos.app.category>Traffic Steering</onos.app.category>
         <onos.app.title>VLAN L2 Broadcast Network App</onos.app.title>
         <onos.app.url>http://onosproject.org</onos.app.url>
+        <onos.app.requires>org.onosproject.intentsynchronizer</onos.app.requires>
     </properties>
 
     <dependencies>
@@ -44,12 +45,7 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-app-routing-api</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-app-routing</artifactId>
+            <artifactId>onos-apps-intentsync</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
index 7b4667b..94b819a 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/IntentInstaller.java
@@ -36,7 +36,7 @@
 import org.onosproject.net.intent.SinglePointToMultiPointIntent;
 import org.onosproject.net.intent.constraint.EncapsulationConstraint;
 import org.onosproject.net.intent.constraint.PartialFailureConstraint;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
index 444b5aa..af47248 100644
--- a/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
+++ b/apps/vpls/src/main/java/org/onosproject/vpls/Vpls.java
@@ -49,7 +49,7 @@
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.Key;
-import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.vpls.config.VplsConfigService;
 import org.slf4j.Logger;
 
diff --git a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
index 5f5aaec..3ebc858 100644
--- a/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
+++ b/apps/vpls/src/test/java/org/onosproject/vpls/VplsTest.java
@@ -36,6 +36,7 @@
 import org.onosproject.incubator.net.intf.Interface;
 import org.onosproject.incubator.net.intf.InterfaceListener;
 import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.intentsync.IntentSynchronizationService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultHost;
 import org.onosproject.net.DeviceId;
@@ -62,8 +63,6 @@
 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
 import org.onosproject.net.intent.SinglePointToMultiPointIntent;
 import org.onosproject.net.provider.ProviderId;
-import org.onosproject.routing.IntentSynchronizationAdminService;
-import org.onosproject.routing.IntentSynchronizationService;
 import org.onosproject.vpls.config.VplsConfigService;
 
 import java.util.Collection;
@@ -77,11 +76,20 @@
 import java.util.stream.Collectors;
 
 import static java.lang.String.format;
-import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
-import static org.onosproject.net.EncapsulationType.*;
-import static org.onosproject.vpls.IntentInstaller.*;
+import static org.onosproject.net.EncapsulationType.NONE;
+import static org.onosproject.net.EncapsulationType.VLAN;
+import static org.onosproject.net.EncapsulationType.valueOf;
+import static org.onosproject.vpls.IntentInstaller.PARTIAL_FAILURE_CONSTRAINT;
+import static org.onosproject.vpls.IntentInstaller.PREFIX_BROADCAST;
+import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
+import static org.onosproject.vpls.IntentInstaller.setEncap;
 
 /**
  * Tests for the {@link Vpls} class.
@@ -808,8 +816,7 @@
      * Test IntentSynchronizer that passes all intents straight through to the
      * intent service.
      */
-    private class TestIntentSynchronizer implements IntentSynchronizationService,
-            IntentSynchronizationAdminService {
+    private class TestIntentSynchronizer implements IntentSynchronizationService {
 
         private final IntentService intentService;
 
@@ -833,14 +840,6 @@
         }
 
         @Override
-        public void modifyPrimary(boolean isPrimary) {
-        }
-
-        @Override
-        public void removeIntents() {
-        }
-
-        @Override
         public void removeIntentsByAppId(ApplicationId applicationId) {
         }
     }
diff --git a/modules.defs b/modules.defs
index 0fd1c0f..1640494 100644
--- a/modules.defs
+++ b/modules.defs
@@ -133,6 +133,7 @@
     '//apps/gangliametrics:onos-apps-gangliametrics-oar',
     '//apps/graphitemetrics:onos-apps-graphitemetrics-oar',
     '//apps/flowanalyzer:onos-apps-flowanalyzer-oar',
+    '//apps/intentsync:onos-apps-intentsync-oar',
     '//apps/influxdbmetrics:onos-apps-influxdbmetrics-oar',
     '//apps/metrics:onos-apps-metrics-oar',
     '//apps/mfwd:onos-apps-mfwd-oar',