Committed by
Gerrit Code Review
Ensure ApplicationManager waits until features are installed/uninstalled
Change-Id: Ie86c7945d8707cac6ef869e0b28bb950744ea708
Showing
1 changed file
with
21 additions
and
14 deletions
| ... | @@ -47,6 +47,7 @@ import java.io.InputStream; | ... | @@ -47,6 +47,7 @@ import java.io.InputStream; |
| 47 | import java.util.Set; | 47 | import java.util.Set; |
| 48 | import java.util.concurrent.CountDownLatch; | 48 | import java.util.concurrent.CountDownLatch; |
| 49 | import java.util.concurrent.TimeUnit; | 49 | import java.util.concurrent.TimeUnit; |
| 50 | +import java.util.function.Consumer; | ||
| 50 | 51 | ||
| 51 | import static com.google.common.base.Preconditions.checkNotNull; | 52 | import static com.google.common.base.Preconditions.checkNotNull; |
| 52 | import static org.onosproject.app.ApplicationEvent.Type.APP_ACTIVATED; | 53 | import static org.onosproject.app.ApplicationEvent.Type.APP_ACTIVATED; |
| ... | @@ -83,7 +84,7 @@ public class ApplicationManager | ... | @@ -83,7 +84,7 @@ public class ApplicationManager |
| 83 | 84 | ||
| 84 | // Application supplied hooks for pre-activation processing. | 85 | // Application supplied hooks for pre-activation processing. |
| 85 | private final Multimap<String, Runnable> deactivateHooks = HashMultimap.create(); | 86 | private final Multimap<String, Runnable> deactivateHooks = HashMultimap.create(); |
| 86 | - private final Cache<ApplicationId, CountDownLatch> pendingUninstalls = | 87 | + private final Cache<ApplicationId, CountDownLatch> pendingOperations = |
| 87 | CacheBuilder.newBuilder() | 88 | CacheBuilder.newBuilder() |
| 88 | .expireAfterWrite(DEFAULT_OPERATION_TIMEOUT_MILLIS * 2, TimeUnit.MILLISECONDS) | 89 | .expireAfterWrite(DEFAULT_OPERATION_TIMEOUT_MILLIS * 2, TimeUnit.MILLISECONDS) |
| 89 | .build(); | 90 | .build(); |
| ... | @@ -160,15 +161,7 @@ public class ApplicationManager | ... | @@ -160,15 +161,7 @@ public class ApplicationManager |
| 160 | public void uninstall(ApplicationId appId) { | 161 | public void uninstall(ApplicationId appId) { |
| 161 | checkNotNull(appId, APP_ID_NULL); | 162 | checkNotNull(appId, APP_ID_NULL); |
| 162 | CountDownLatch latch = new CountDownLatch(1); | 163 | CountDownLatch latch = new CountDownLatch(1); |
| 163 | - try { | 164 | + updateStoreAndWaitForNotificationHandling(appId, store::remove); |
| 164 | - pendingUninstalls.put(appId, latch); | ||
| 165 | - store.remove(appId); | ||
| 166 | - } catch (Exception e) { | ||
| 167 | - pendingUninstalls.invalidate(appId); | ||
| 168 | - latch.countDown(); | ||
| 169 | - log.warn("Unable to purge application directory for {}", appId.name()); | ||
| 170 | - } | ||
| 171 | - Uninterruptibles.awaitUninterruptibly(latch, DEFAULT_OPERATION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); | ||
| 172 | } | 165 | } |
| 173 | 166 | ||
| 174 | @Override | 167 | @Override |
| ... | @@ -177,13 +170,13 @@ public class ApplicationManager | ... | @@ -177,13 +170,13 @@ public class ApplicationManager |
| 177 | if (!SecurityUtil.isAppSecured(appId)) { | 170 | if (!SecurityUtil.isAppSecured(appId)) { |
| 178 | return; | 171 | return; |
| 179 | } | 172 | } |
| 180 | - store.activate(appId); | 173 | + updateStoreAndWaitForNotificationHandling(appId, store::activate); |
| 181 | } | 174 | } |
| 182 | 175 | ||
| 183 | @Override | 176 | @Override |
| 184 | public void deactivate(ApplicationId appId) { | 177 | public void deactivate(ApplicationId appId) { |
| 185 | checkNotNull(appId, APP_ID_NULL); | 178 | checkNotNull(appId, APP_ID_NULL); |
| 186 | - store.deactivate(appId); | 179 | + updateStoreAndWaitForNotificationHandling(appId, store::deactivate); |
| 187 | } | 180 | } |
| 188 | 181 | ||
| 189 | @Override | 182 | @Override |
| ... | @@ -193,12 +186,26 @@ public class ApplicationManager | ... | @@ -193,12 +186,26 @@ public class ApplicationManager |
| 193 | store.setPermissions(appId, permissions); | 186 | store.setPermissions(appId, permissions); |
| 194 | } | 187 | } |
| 195 | 188 | ||
| 189 | + private void updateStoreAndWaitForNotificationHandling(ApplicationId appId, | ||
| 190 | + Consumer<ApplicationId> storeUpdateTask) { | ||
| 191 | + CountDownLatch latch = new CountDownLatch(1); | ||
| 192 | + try { | ||
| 193 | + pendingOperations.put(appId, latch); | ||
| 194 | + storeUpdateTask.accept(appId); | ||
| 195 | + } catch (Exception e) { | ||
| 196 | + pendingOperations.invalidate(appId); | ||
| 197 | + latch.countDown(); | ||
| 198 | + log.warn("Failed to update store for {}", appId.name(), e); | ||
| 199 | + } | ||
| 200 | + Uninterruptibles.awaitUninterruptibly(latch, DEFAULT_OPERATION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); | ||
| 201 | + } | ||
| 202 | + | ||
| 196 | private class InternalStoreDelegate implements ApplicationStoreDelegate { | 203 | private class InternalStoreDelegate implements ApplicationStoreDelegate { |
| 197 | @Override | 204 | @Override |
| 198 | public void notify(ApplicationEvent event) { | 205 | public void notify(ApplicationEvent event) { |
| 199 | ApplicationEvent.Type type = event.type(); | 206 | ApplicationEvent.Type type = event.type(); |
| 200 | Application app = event.subject(); | 207 | Application app = event.subject(); |
| 201 | - CountDownLatch latch = pendingUninstalls.getIfPresent(app.id()); | 208 | + CountDownLatch latch = pendingOperations.getIfPresent(app.id()); |
| 202 | try { | 209 | try { |
| 203 | if (type == APP_ACTIVATED) { | 210 | if (type == APP_ACTIVATED) { |
| 204 | if (installAppFeatures(app)) { | 211 | if (installAppFeatures(app)) { |
| ... | @@ -227,7 +234,7 @@ public class ApplicationManager | ... | @@ -227,7 +234,7 @@ public class ApplicationManager |
| 227 | } finally { | 234 | } finally { |
| 228 | if (latch != null) { | 235 | if (latch != null) { |
| 229 | latch.countDown(); | 236 | latch.countDown(); |
| 230 | - pendingUninstalls.invalidate(app.id()); | 237 | + pendingOperations.invalidate(app.id()); |
| 231 | } | 238 | } |
| 232 | } | 239 | } |
| 233 | } | 240 | } | ... | ... |
-
Please register or login to post a comment