@Override
  public Object perform(String name, Object obj, ApiRequest request) {
    if (!(obj instanceof Service)) {
      return null;
    }
    final Service service = (Service) obj;

    final Map<String, ServiceLink> newServiceLinks = populateNewServiceLinks(request);

    validateLinks(newServiceLinks);
    if (newServiceLinks != null) {
      lockManager.lock(
          new ServiceDiscoveryServiceSetLinksLock(service),
          new LockCallbackNoReturn() {
            @Override
            public void doWithLockNoResult() {
              // remove old listeners set
              removeOldServiceMaps(service, newServiceLinks);

              // create a new set
              createNewServiceMaps(service, newServiceLinks);
            }
          });
    }

    return service;
  }
  @Override
  public void remove(final Service service) {
    // do with lock to prevent intervention to sidekick service activate
    lockManager.lock(
        createLock(Arrays.asList(service)),
        new LockCallbackNoReturn() {
          @Override
          public void doWithLockNoResult() {
            // in remove, we don't care about the sidekicks, and remove only requested service
            deleteServiceInstances(service);
            List<? extends ServiceExposeMap> unmanagedMaps =
                expMapDao.getUnmanagedServiceInstanceMapsToRemove(service.getId());
            for (ServiceExposeMap unmanagedMap : unmanagedMaps) {
              objectProcessMgr.scheduleStandardProcessAsync(
                  StandardProcess.REMOVE, unmanagedMap, null);
            }
            sdSvc.removeServiceMaps(service);
          }

          protected void deleteServiceInstances(final Service service) {
            List<DeploymentUnit> units =
                unitInstanceFactory.collectDeploymentUnits(
                    Arrays.asList(service), new DeploymentServiceContext());
            for (DeploymentUnit unit : units) {
              unit.remove(false, ServiceDiscoveryConstants.AUDIT_LOG_REMOVE_EXTRA);
            }
          }
        });
  }
Example #3
0
  @Override
  public HandlerResult handle(ProcessState state, ProcessInstance process) {
    final Instance instance = (Instance) state.getResource();

    List<Volume> volumes = InstanceHelpers.extractVolumesFromMounts(instance, objectManager);
    for (final Volume v : volumes) {
      String driver = DataAccessor.fieldString(v, VolumeConstants.FIELD_VOLUME_DRIVER);
      if (StringUtils.isNotEmpty(driver) && !VolumeConstants.LOCAL_DRIVER.equals(driver)) {
        StoragePool sp = storagePoolDao.findStoragePoolByDriverName(v.getAccountId(), driver);
        if (sp == null) {
          continue;
        }
        final String accessMode = sp.getVolumeAccessMode();
        if (StringUtils.isNotEmpty(accessMode)
            && StringUtils.isEmpty(v.getAccessMode())
            && !accessMode.equals(v.getAccessMode())) {
          lockManager.lock(
              new InstanceVolumeAccessModeLock(v.getId()),
              new LockCallbackNoReturn() {
                @Override
                public void doWithLockNoResult() {
                  objectManager.setFields(v, VOLUME.ACCESS_MODE, accessMode);
                }
              });
        }
      }
    }

    return null;
  }
 @Override
 public List<? extends ProjectMember> setProjectMembers(
     final Account project, final Set<Member> members) {
   return lockManager.lock(
       new ProjectLock(project),
       new LockCallback<List<? extends ProjectMember>>() {
         public List<? extends ProjectMember> doWithLock() {
           List<? extends ProjectMember> previousMembers =
               getActiveProjectMembers(project.getId());
           Set<Member> otherPreviosMembers = new HashSet<>();
           for (ProjectMember member : previousMembers) {
             String projectId =
                 (String)
                     ApiContext.getContext()
                         .getIdFormatter()
                         .formatId(objectManager.getType(Account.class), member.getProjectId());
             otherPreviosMembers.add(new Member(member, projectId));
           }
           Set<Member> create = new HashSet<Member>(members);
           Set<Member> delete = new HashSet<Member>(otherPreviosMembers);
           for (Member member : members) {
             if (delete.remove(member)) {
               create.remove(member);
             }
           }
           Condition allMembers = DSL.falseCondition();
           for (Member member : delete) {
             allMembers =
                 allMembers.or(
                     PROJECT_MEMBER
                         .EXTERNAL_ID
                         .eq(member.getExternalId())
                         .and(PROJECT_MEMBER.EXTERNAL_ID_TYPE.eq(member.getExternalIdType()))
                         .and(PROJECT_MEMBER.PROJECT_ID.eq(project.getId()))
                         .and(PROJECT_MEMBER.STATE.eq(CommonStatesConstants.ACTIVE)));
           }
           List<? extends ProjectMember> toDelete =
               create().selectFrom(PROJECT_MEMBER).where(allMembers).fetch();
           for (ProjectMember member : toDelete) {
             objectProcessManager.executeStandardProcess(StandardProcess.DEACTIVATE, member, null);
             objectProcessManager.executeStandardProcess(StandardProcess.REMOVE, member, null);
           }
           List<ProjectMember> newMembers = new ArrayList<>();
           for (Member member : create) {
             newMembers.add(createProjectMember(project, member));
           }
           return getActiveProjectMembers(project.getId());
         }
       });
 }
  /**
   * @param service
   * @param checkState
   * @return true if this service needs to be reconciled
   */
  protected boolean activate(final Service service, final boolean checkState) {
    // return immediately if inactive
    if (service == null || !sdSvc.isActiveService(service)) {
      return false;
    }

    final List<Service> services = new ArrayList<>();
    services.add(service);

    return lockManager.lock(
        checkState ? null : createLock(services),
        new LockCallback<Boolean>() {
          @Override
          public Boolean doWithLock() {
            if (!sdSvc.isActiveService(service)) {
              return false;
            }
            // get existing deployment units
            ServiceDeploymentPlanner planner = getPlanner(services);

            // don't process if there is no need to reconcile
            boolean needToReconcile = needToReconcile(services, planner);

            if (!needToReconcile) {
              return false;
            }

            if (checkState) {
              return !planner.isHealthcheckInitiailizing();
            }

            activateServices(service, services);
            activateDeploymentUnits(planner);

            // reload planner as there can be new hosts added for Global services
            planner = getPlanner(services);
            if (needToReconcile(services, planner)) {
              throw new IllegalStateException(
                  "Failed to do service reconcile for service [" + service.getId() + "]");
            }

            return false;
          }
        });
  }
 @Override
 public void deactivate(final Service service) {
   // do with lock to prevent intervention to sidekick service activate
   lockManager.lock(
       createLock(Arrays.asList(service)),
       new LockCallbackNoReturn() {
         @Override
         public void doWithLockNoResult() {
           // in deactivate, we don't care about the sidekicks, and deactivate only requested
           // service
           List<DeploymentUnit> units =
               unitInstanceFactory.collectDeploymentUnits(
                   Arrays.asList(service), new DeploymentServiceContext());
           for (DeploymentUnit unit : units) {
             unit.stop();
           }
         }
       });
 }
  @Override
  public HandlerResult handle(ProcessState state, ProcessInstance process) {
    final ExternalEvent event = (ExternalEvent) state.getResource();

    if (!ExternalEventConstants.KIND_SERVICE_EVENT.equals(event.getKind())) {
      return null;
    }

    lockManager.lock(
        new ExternalEventLock(SERVICE_LOCK_NAME, event.getAccountId(), event.getExternalId()),
        new LockCallbackNoReturn() {
          @Override
          public void doWithLockNoResult() {
            Map<String, Object> serviceData =
                CollectionUtils.toMap(DataUtils.getFields(event).get(FIELD_SERVICE));
            if (serviceData.isEmpty()) {
              log.warn("Empty service for externalServiceEvent: {}.", event);
              return;
            }

            String kind =
                serviceData.get(ObjectMetaDataManager.KIND_FIELD) != null
                    ? serviceData.get(ObjectMetaDataManager.KIND_FIELD).toString()
                    : null;
            if (StringUtils.isEmpty(kind) || schemaFactory.getSchema(kind) == null) {
              log.warn("Couldn't find schema for service type [{}]. Returning.", kind);
              return;
            }

            if (StringUtils.equals(event.getEventType(), TYPE_SERVICE_CREATE)) {
              createService(event, serviceData);
            } else if (StringUtils.equals(event.getEventType(), TYPE_SERVICE_UPDATE)) {
              updateService(event, serviceData);
            } else if (StringUtils.equals(event.getEventType(), TYPE_SERVICE_DELETE)) {
              deleteService(event, serviceData);
            } else if (StringUtils.equals(event.getEventType(), TYPE_STACK_DELETE)) {
              deleteStack(event, serviceData);
            }
          }
        });
    return null;
  }
Example #8
0
  @Override
  public HandlerResult handle(ProcessState state, ProcessInstance process) {
    Port port = (Port) state.getResource();
    final Instance instance = getObjectManager().loadResource(Instance.class, port.getInstanceId());

    if (instance == null) {
      return null;
    }

    lockManager.lock(
        new InstancePortsLock(instance),
        new LockCallbackNoReturn() {
          @Override
          public void doWithLockNoResult() {
            processPorts(instance);
          }
        });

    return null;
  }
Example #9
0
  protected void restartDeploymentUnits(
      final Service service, final Map<String, List<Instance>> deploymentUnitsToStop) {

    // hold the lock so service.reconcile triggered by config.update
    // (in turn triggered by instance.remove) won't interfere

    lockManager.lock(
        new ServicesSidekickLock(Arrays.asList(service)),
        new LockCallbackNoReturn() {
          @Override
          public void doWithLockNoResult() {
            // 1. Wait for the service instances to become healthy
            waitForHealthyState(service);
            // 2. stop instances
            stopInstances(deploymentUnitsToStop);
            // 3. wait for reconcile (instances will be restarted along)
            deploymentMgr.activate(service);
          }
        });
  }
Example #10
0
  protected void upgradeDeploymentUnits(
      final Service service,
      final Map<String, List<Instance>> deploymentUnitInstancesToUpgrade,
      final Map<String, List<Instance>> deploymentUnitInstancesUpgradedManaged,
      final Map<String, List<Instance>> deploymentUnitInstancesUpgradedUnmanaged,
      final Map<String, List<Instance>> deploymentUnitInstancesToCleanup,
      final long batchSize,
      final boolean startFirst,
      final boolean fullUpgrade,
      final boolean isUpgrade) {
    // hold the lock so service.reconcile triggered by config.update
    // (in turn triggered by instance.remove) won't interfere
    lockManager.lock(
        new ServicesSidekickLock(Arrays.asList(service)),
        new LockCallbackNoReturn() {
          @Override
          public void doWithLockNoResult() {
            // wait for healthy only for upgrade
            // should be skipped for rollback
            if (isUpgrade) {
              waitForHealthyState(service);
            }
            // mark for upgrade
            markForUpgrade(batchSize);

            if (startFirst) {
              // 1. reconcile to start new instances
              deploymentMgr.activate(service);
              // 2. stop instances
              stopInstances(deploymentUnitInstancesToCleanup);
            } else {
              // reverse order
              // 1. stop instances
              stopInstances(deploymentUnitInstancesToCleanup);
              // 2. wait for reconcile (new instances will be started along)
              deploymentMgr.activate(service);
            }
            if (isUpgrade) {
              waitForHealthyState(service);
            }
          }

          protected void markForUpgrade(final long batchSize) {
            markForCleanup(batchSize, fullUpgrade);
          }

          protected void markForCleanup(final long batchSize, boolean fullUpgrade) {
            long i = 0;
            Iterator<Map.Entry<String, List<Instance>>> it =
                deploymentUnitInstancesToUpgrade.entrySet().iterator();
            while (it.hasNext() && i < batchSize) {
              Map.Entry<String, List<Instance>> instances = it.next();
              String deploymentUnitUUID = instances.getKey();
              markForRollback(deploymentUnitUUID);
              for (Instance instance : instances.getValue()) {
                ServiceExposeMap map =
                    objectManager.findAny(
                        ServiceExposeMap.class, SERVICE_EXPOSE_MAP.INSTANCE_ID, instance.getId());
                setUpgrade(map, true);
              }
              deploymentUnitInstancesToCleanup.put(deploymentUnitUUID, instances.getValue());
              it.remove();
              i++;
            }
          }

          protected void markForRollback(String deploymentUnitUUIDToRollback) {
            List<Instance> instances = new ArrayList<>();
            if (fullUpgrade) {
              // for full upgrade, we don't care what deployment unit needs to be rolled back
              String toExtract = null;
              for (String key : deploymentUnitInstancesUpgradedUnmanaged.keySet()) {
                if (toExtract != null) {
                  break;
                }
                toExtract = key;
              }
              instances = deploymentUnitInstancesUpgradedUnmanaged.get(toExtract);
              deploymentUnitInstancesUpgradedUnmanaged.remove(toExtract);
            } else {
              // for partial upgrade, rollback a specific deployment unit
              instances =
                  deploymentUnitInstancesUpgradedUnmanaged.get(deploymentUnitUUIDToRollback);
            }
            if (instances != null) {
              for (Instance instance : instances) {
                ServiceExposeMap map =
                    objectManager.findAny(
                        ServiceExposeMap.class, SERVICE_EXPOSE_MAP.INSTANCE_ID, instance.getId());
                setUpgrade(map, false);
              }
              deploymentUnitInstancesUpgradedManaged.put(deploymentUnitUUIDToRollback, instances);
            }
          }
        });
  }