Package org.platformlayer.xaas.web.resources

Source Code of org.platformlayer.xaas.web.resources.ItemServiceImpl

package org.platformlayer.xaas.web.resources;

import java.util.List;

import javax.inject.Inject;
import javax.inject.Singleton;

import org.platformlayer.CheckedCallable;
import org.platformlayer.Filter;
import org.platformlayer.RepositoryException;
import org.platformlayer.StateFilter;
import org.platformlayer.TagFilter;
import org.platformlayer.auth.crypto.SecretProvider;
import org.platformlayer.core.model.ItemBase;
import org.platformlayer.core.model.ManagedItemState;
import org.platformlayer.core.model.PlatformLayerKey;
import org.platformlayer.core.model.Tag;
import org.platformlayer.core.model.TagChanges;
import org.platformlayer.ids.ManagedItemId;
import org.platformlayer.ids.ProjectId;
import org.platformlayer.ids.ServiceType;
import org.platformlayer.jobs.model.JobData;
import org.platformlayer.model.ProjectAuthorization;
import org.platformlayer.ops.ItemService;
import org.platformlayer.ops.OpsContext;
import org.platformlayer.ops.OpsException;
import org.platformlayer.ops.OpsSystem;
import org.platformlayer.ops.tasks.OpsContextBuilder;
import org.platformlayer.xaas.repository.ManagedItemRepository;
import org.platformlayer.xaas.services.ChangeQueue;
import org.platformlayer.xaas.services.ModelClass;
import org.platformlayer.xaas.services.ServiceProvider;
import org.platformlayer.xaas.services.ServiceProviderDictionary;
import org.platformlayer.xml.JaxbHelper;
import org.platformlayer.xml.JsonHelper;

import com.fathomdb.Casts;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.inject.Injector;

@Singleton
public class ItemServiceImpl implements ItemService {
  @Inject
  protected ManagedItemRepository repository;

  @Inject
  protected ChangeQueue changeQueue;

  @Inject
  Injector injector;

  @Inject
  OpsSystem opsSystem;

  @Inject
  ServiceProviderDictionary serviceProviderDirectory;

  // @Override
  // public List<ManagedItem<Object>> listItems(ModelKey modelKey) throws RepositoryException {
  // boolean fetchTags = true;
  // List<ManagedItem<Object>> items = repository.getByAccountId(modelKey, fetchTags);
  // return items;
  // // ManagedItemCollection<T> collection = new ManagedItemCollection<T>();
  // // collection.items = items;
  // // return collection;
  // }

  @Override
  public <T extends ItemBase> List<T> findAll(ProjectAuthorization authentication, Class<T> itemClass)
      throws OpsException {
    ModelClass<T> modelClass = serviceProviderDirectory.getModelClass(itemClass);

    if (modelClass == null) {
      throw new IllegalArgumentException();
    }
    // if (modelClass.isSystemObject()) {
    // if (!isInRole(authentication, RoleId.ADMIN)) {
    // throw new SecurityException();
    // }
    // }

    // Class<T> javaClass = modelClass.getJavaClass();

    ProjectId project = getProjectId(authentication);

    // ModelKey modelKey = new ModelKey(modelClass.getServiceType(), modelClass.getItemType(), project, null);

    // if (isSystemObject(modelKey)) {
    // checkLoggedInAsAdmin();
    // }

    boolean fetchTags = true;
    List<T> items;
    try {
      items = repository.findAll(modelClass, project, fetchTags, getSecretProvider(authentication), Filter.EMPTY);
    } catch (RepositoryException e) {
      throw new OpsException("Error reading objects from database", e);
    }
    return items;
    //
    // List<ManagedItem<Object>> listItems = itemService.listItems(modelKey);
    //
    // ServiceProvider serviceProvider = serviceProviderDictionary.getServiceProvider(serviceType);
    // Class<?> javaClass = serviceProvider.getJavaClass(itemType);
    //
    // List<AptCacheService> typedItems = Lists.newArrayList();
    // for (ManagedItem<Object> item : listItems) {
    // ModelKey itemKey = new ModelKey(serviceType, itemType, project, new ManagedItemId(item.getKey()));
    // TypedManagedItem<?> typedManagedItem = TypedManagedItem.build(javaClass, itemKey, item);
    // typedItems.add((AptCacheService) typedManagedItem.getModel());
    // }
    //
    // return typedItems;
  }

  private SecretProvider getSecretProvider(ProjectAuthorization authz) {
    return SecretProvider.from(authz);
  }

  // @Override
  // public <T> ManagedItem<T> createItem(Authentication auth, ModelKey modelKey, ManagedItem<T> untypedItem) throws
  // RepositoryException, OpsException {
  // // ModelKey modelKey = item.getModelKey();
  // ServiceProvider serviceProvider = opsSystem.getServiceProvider(modelKey.getServiceType());
  //
  // Class<T> javaClass = (Class<T>) opsSystem.getJavaClass(modelKey);
  //
  // TypedManagedItem<T> item = TypedManagedItem.build(javaClass, modelKey, untypedItem);
  // // ModelClass modelClass = item.getModelClass();
  // // ServiceProvider serviceProvider = modelClass.getProvider();
  //
  // item.setState(ManagedItemState.CREATION_REQUESTED);
  // String modelData = item.getModelData();
  // if (Strings.isNullOrEmpty(modelData))
  // throw new IllegalArgumentException("ModelData is required");
  //
  // modelData = modelData.trim();
  // if (modelData.startsWith("{")) {
  // // Convert JSON to XML
  // JsonHelper<?> jsonHelper = getJsonHelper(modelKey);
  //
  // String json = jsonHelper.wrapJson(modelData);
  //
  // Object model;
  // try {
  // jsonHelper.addDefaultNamespace();
  // model = jsonHelper.unmarshal(json);
  // } catch (Exception e) {
  // throw new IllegalArgumentException("Could not parse model data", e);
  // }
  // JaxbHelper jaxbHelper = getJaxbHelper(modelKey);
  // String xml;
  // try {
  // xml = jaxbHelper.marshal(model, false);
  // } catch (JAXBException e) {
  // throw new IllegalArgumentException("Could not convert JSON to XML", e);
  // }
  // item.setModelData(xml);
  // }
  //
  // serviceProvider.beforeCreateItem(item);
  //
  // {
  // // Set the model data, in case we have changed it
  // JaxbHelper jaxbHelper = getJaxbHelper(modelKey);
  // String xml;
  // try {
  // xml = jaxbHelper.marshal(item.getModel(), false);
  // } catch (JAXBException e) {
  // throw new IllegalArgumentException("Could not convert JSON to XML", e);
  // }
  // item.setModelData(xml);
  // }
  //
  // // ProjectId project = new ProjectId(auth.getProject());
  //
  // ManagedItem created = repository.createManagedItem(modelKey, item.getSerialized());
  //
  // changeQueue.notifyChange(serviceProvider.getServiceType(), auth, item);
  //
  // return item.getSerialized();
  // }

  // protected boolean isInRole(ProjectAuthorization auth, RoleId role) {
  // return auth.isInRole(auth.getProjectId(), role);
  // }

  private JsonHelper<?> getJsonHelper(PlatformLayerKey modelKey) {
    Class<?> javaClass = opsSystem.getJavaClass(modelKey);
    return JsonHelper.build(javaClass);
  }

  private JaxbHelper getJaxbHelper(PlatformLayerKey modelKey) {
    Class<?> javaClass = opsSystem.getJavaClass(modelKey);
    return JaxbHelper.get(javaClass);
  }

  @Override
  public <T extends ItemBase> T createItem(final ProjectAuthorization auth, final T item, boolean generateUniqueName)
      throws OpsException {
    return ensureItem(auth, item, false, generateUniqueName, null);
  }

  <T extends ItemBase> T ensureItem(final ProjectAuthorization auth, final T item, final boolean canExist,
      final boolean generateUniqueName, final String uniqueTagKey) throws OpsException {
    final ModelClass<T> modelClass = (ModelClass<T>) serviceProviderDirectory.getModelClass(item.getClass());
    if (modelClass == null) {
      throw new IllegalStateException("Unknown item type");
    }
    final Class<T> javaClass = modelClass.getJavaClass();

    // JaxbHelper jaxbHelper = JaxbHelper.get(javaClass);

    final ServiceProvider serviceProvider = modelClass.getProvider();

    String id = item.getId();

    if (Strings.isNullOrEmpty(id)) {
      if (generateUniqueName) {
        id = serviceProvider.buildItemId(modelClass, item);
      } else {
        // TODO: We could auto-generate this, but it seems better to require it,
        // otherwise we end up with lots of randomly named items
        throw new OpsException("Must specify item id");
        // id = UUID.randomUUID().toString();
        // item.setId(id);
      }
    }

    ProjectId project = getProjectId(auth);
    PlatformLayerKey itemKey = new PlatformLayerKey(null, project, modelClass.getServiceType(),
        modelClass.getItemType(), new ManagedItemId(id));
    item.setKey(itemKey);

    item.state = ManagedItemState.CREATION_REQUESTED;

    final OpsContext opsContext = buildTemporaryOpsContext(modelClass.getServiceType(), auth);

    T created = OpsContext.runInContext(opsContext, new CheckedCallable<T, Exception>() {
      @Override
      public T call() throws Exception {
        PlatformLayerKey itemKey = item.getKey();

        T existing;

        SecretProvider secretProvider = SecretProvider.from(auth);

        if (uniqueTagKey != null) {
          boolean fetchTags = true;
          Tag uniqueTag = null;
          for (Tag tag : item.getTags()) {
            if (Objects.equal(tag.getKey(), uniqueTagKey)) {
              uniqueTag = tag;
            }
          }
          if (uniqueTag == null) {
            throw new IllegalArgumentException("Could not find unique tag");
          }
          Filter filter = TagFilter.byTag(uniqueTag);
          filter = StateFilter.excludeDeleted(filter);

          existing = null;
          List<T> existingList = repository.findAll(modelClass, itemKey.getProject(), fetchTags,
              secretProvider, filter);
          if (!existingList.isEmpty()) {
            if (existingList.size() != 1) {
              throw new IllegalArgumentException("Found multiple items with unique tag");
            }
            existing = existingList.get(0);
          }

          if (existing == null) {
            itemKey = findUniqueId(item, itemKey, secretProvider);
          }
        } else {
          if (generateUniqueName) {
            itemKey = findUniqueId(item, itemKey, secretProvider);
          }

          try {
            boolean fetchTags = true;
            existing = Casts.checkedCast(repository.getManagedItem(itemKey, fetchTags, secretProvider),
                javaClass);
          } catch (RepositoryException e) {
            throw new OpsException("Error fetching item from database", e);
          }
        }

        if (!canExist && existing != null) {
          throw new OpsException("Item already exists");
        }

        serviceProvider.beforeCreateItem(item);

        ProjectId project = getProjectId(auth);
        T newItem;
        try {
          if (existing == null) {
            newItem = repository.createManagedItem(project, item);
          } else {
            item.secret = existing.secret;
            item.setKey(existing.getKey());

            newItem = repository.updateManagedItem(project, item);

            TagChanges tagChanges = new TagChanges();
            for (Tag tag : item.getTags()) {
              if (newItem.getTags().hasTag(tag)) {
                continue;
              }

              boolean uniqueTagKey = false;
              if (tag.getKey().equals(Tag.PARENT.getKey())) {
                uniqueTagKey = true;
              }

              tagChanges.addTags.add(tag);

              if (uniqueTagKey) {
                for (Tag oldTag : newItem.getTags().findTags(tag.getKey())) {
                  tagChanges.removeTags.add(oldTag);
                }
              }
            }

            if (!tagChanges.isEmpty()) {
              repository.changeTags(modelClass, project, newItem.getKey().getItemId(), tagChanges, null);
            }
          }
        } catch (RepositoryException e) {
          throw new OpsException("Error writing object to database", e);
        }

        itemKey = newItem.getKey();
        JobData jobKey = changeQueue.notifyChange(auth, itemKey, ManagedItemState.CREATION_REQUESTED);
        // returnJobKey(jobKey);

        return newItem;
      }

      private <T extends ItemBase> PlatformLayerKey findUniqueId(final T item, final PlatformLayerKey itemKey,
          SecretProvider secretProvider) throws RepositoryException {
        int sequence = 0;
        while (true) {
          String tryId = item.getId();
          if (sequence != 0) {
            tryId += sequence;
          }
          final PlatformLayerKey tryKey = itemKey.withId(new ManagedItemId(tryId));
          boolean fetchTags = false;
          ItemBase found = repository.getManagedItem(tryKey, fetchTags, secretProvider);
          if (found == null) {
            item.setKey(tryKey);
            return tryKey;
          }
          sequence++;
        }
      }
    });

    return created;
  }

  @Override
  public <T extends ItemBase> T putItem(final ProjectAuthorization auth, final T item, String uniqueTag)
      throws OpsException {
    boolean generateUniqueName = false;
    return ensureItem(auth, item, true, generateUniqueName, uniqueTag);
  }

  protected OpsContext buildTemporaryOpsContext(ServiceType serviceType, ProjectAuthorization auth)
      throws OpsException {
    OpsContextBuilder opsContextBuilder = injector.getInstance(OpsContextBuilder.class);
    return opsContextBuilder.buildTemporaryOpsContext(serviceType, auth);
  }

  @Override
  public JobData deleteItem(final ProjectAuthorization auth, final PlatformLayerKey targetItemKey)
      throws OpsException {
    SecretProvider secretProvider = SecretProvider.from(auth);

    boolean fetchTags = true;
    ItemBase targetItem;
    try {
      targetItem = repository.getManagedItem(targetItemKey, fetchTags, secretProvider);
    } catch (RepositoryException e) {
      throw new OpsException("Error reading item", e);
    }

    if (targetItem == null) {
      throw new IllegalStateException("Item not found");
    }

    targetItem.state = ManagedItemState.DELETE_REQUESTED;

    final ServiceProvider serviceProvider = serviceProviderDirectory.getServiceProvider(targetItemKey
        .getServiceType());
    if (serviceProvider == null) {
      throw new IllegalStateException("Unknown service type");
    }

    final OpsContext opsContext = buildTemporaryOpsContext(targetItemKey.getServiceType(), auth);

    JobData jobKey = OpsContext.runInContext(opsContext, new CheckedCallable<JobData, Exception>() {
      @Override
      public JobData call() throws Exception {
        try {
          repository.changeState(targetItemKey, ManagedItemState.DELETE_REQUESTED);
        } catch (RepositoryException e) {
          throw new OpsException("Error writing object to database", e);
        }

        return changeQueue.notifyChange(auth, targetItemKey, ManagedItemState.DELETE_REQUESTED);
      }
    });
    return jobKey;
  }

  @Override
  public <T extends ItemBase> T findItem(ProjectAuthorization auth, Class<T> itemClass, String id)
      throws OpsException {
    ModelClass<T> modelClass = serviceProviderDirectory.getModelClass(itemClass);
    // Class<T> javaClass = modelClass.getJavaClass();

    ProjectId project = getProjectId(auth);

    PlatformLayerKey modelKey = new PlatformLayerKey(null, project, modelClass.getServiceType(),
        modelClass.getItemType(), new ManagedItemId(id));

    boolean fetchTags = true;
    T managedItem;
    try {
      managedItem = Casts.checkedCast(repository.getManagedItem(modelKey, fetchTags, SecretProvider.from(auth)),
          itemClass);
    } catch (RepositoryException e) {
      throw new OpsException("Error fetching item from database", e);
    }

    return managedItem;
  }

  @Override
  public List<ItemBase> findRoots(ProjectAuthorization authentication) throws OpsException {
    ProjectId project = getProjectId(authentication);

    boolean fetchTags = true;
    List<ItemBase> items;
    try {
      items = repository.findRoots(project, fetchTags, SecretProvider.from(authentication));
    } catch (RepositoryException e) {
      throw new OpsException("Error reading objects from database", e);
    }
    return items;
  }

  @Override
  public List<ItemBase> listAll(ProjectAuthorization authentication, Filter filter) throws OpsException {
    ProjectId project = getProjectId(authentication);

    List<ItemBase> items;
    try {
      items = repository.listAll(project, filter, SecretProvider.from(authentication));
    } catch (RepositoryException e) {
      throw new OpsException("Error reading objects from database", e);
    }
    return items;
  }

  private ProjectId getProjectId(ProjectAuthorization authentication) {
    String key = authentication.getName();
    if (key == null) {
      throw new IllegalStateException();
    }
    return new ProjectId(key);
  }

  // public void deleteItem(Authentication auth, TypedManagedItem<?> item) throws RepositoryException, OpsException {
  // ModelKey modelKey = item.getModelKey();
  // ServiceProvider serviceProvider = opsSystem.getServiceProvider(modelKey.getServiceType());
  //
  // item.setState(ManagedItemState.DELETE_REQUESTED);
  // serviceProvider.beforeDeleteItem(item);
  //
  // changeQueue.notifyChange(serviceProvider.getServiceType(), auth, item);
  // }
}
TOP

Related Classes of org.platformlayer.xaas.web.resources.ItemServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.