This is an automated email from the ASF dual-hosted git repository.
isjarana pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
The following commit(s) were added to refs/heads/develop by this push:
new 8ea96b9 complete testing sharing management service
new 4034e49 Merge pull request #92 from isururanawaka/sharing_service
8ea96b9 is described below
commit 8ea96b9137b1c73673159b02df91a588c3dae107
Author: Isuru Ranawaka <[email protected]>
AuthorDate: Mon Jul 13 12:40:48 2020 -0400
complete testing sharing management service
---
.../custos/agent/profile/mapper/AgentMapper.java | 2 +-
.../custos/sharing/SharingServiceInitializer.java | 13 +
.../apache/custos/sharing/mapper/EntityMapper.java | 12 +-
.../custos/sharing/mapper/EntityTypeMapper.java | 8 +-
.../sharing/mapper/PermissionTypeMapper.java | 7 +-
.../custos/sharing/mapper/SharingMapper.java | 7 +-
.../custos/sharing/persistance/model/Entity.java | 4 +-
.../custos/sharing/persistance/model/Sharing.java | 14 +-
.../repository/SearchEntityRepository.java | 3 +-
.../repository/SearchEntityRepositoryImpl.java | 11 +-
.../persistance/repository/SharingRepository.java | 12 +-
.../custos/sharing/service/SharingService.java | 85 ++-
.../custos/sharing/validator/InputValidator.java | 4 +-
.../src/main/proto/SharingService.proto | 6 +
.../federatedAuthenticationCoreService.properties | 4 +-
.../main/resources/iamAdminCoreService.properties | 8 +-
.../main/resources/identityCoreService.properties | 8 +-
.../resources/sharingManagementService.properties | 34 +
.../custos-integration-services-commons/pom.xml | 10 +
.../commons/interceptors/AuthInterceptor.java | 12 +
.../interceptors/MultiTenantAuthInterceptor.java | 60 ++
.../commons/utils/InterServiceModelMapper.java | 68 ++
custos-integration-services/pom.xml | 1 +
.../pom.xml | 31 +-
.../sharing-management-service-sidecar/Dockerfile | 3 +
.../sharing-management-service-sidecar/pom.xml | 52 ++
.../src/main/resources/envoy.yaml | 48 ++
.../main/resources/sharing-management-service.pb | Bin 0 -> 85419 bytes
.../sharing-management-service/Dockerfile | 5 +
.../sharing-management-service/pom.xml | 147 +++++
.../src/main/helm/.helmignore | 22 +
.../src/main/helm/Chart.yaml | 5 +
.../src/main/helm/templates/NOTES.txt | 21 +
.../src/main/helm/templates/_helpers.tpl | 56 ++
.../src/main/helm/templates/deployment.yaml | 78 +++
.../src/main/helm/templates/ingress-grpc.yaml | 22 +
.../src/main/helm/templates/ingress.yaml | 21 +
.../src/main/helm/templates/service.yaml | 33 +
.../src/main/helm/templates/serviceaccount.yaml | 8 +
.../main/helm/templates/tests/test-connection.yaml | 15 +
.../src/main/helm/values.yaml | 84 +++
.../SharingManagementServiceInitializer.java | 45 +-
.../management/exceptions/SharingException.java | 12 +-
.../interceptors/AuthInterceptorImpl.java | 121 ++++
.../management/interceptors/InputValidator.java | 111 ++++
.../service/SharingManagementService.java | 693 +++++++++++++++++++++
.../src/main/proto/SharingManagementService.proto | 189 ++++++
.../src/main/resources/application.properties | 27 +
.../src/main/resources/bootstrap.properties | 22 +
49 files changed, 2166 insertions(+), 98 deletions(-)
diff --git
a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/mapper/AgentMapper.java
b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/mapper/AgentMapper.java
index 1694531..0cbbf0b 100644
---
a/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/mapper/AgentMapper.java
+++
b/custos-core-services/agent-profile-core-service/src/main/java/org/apache/custos/agent/profile/mapper/AgentMapper.java
@@ -75,7 +75,6 @@ public class AgentMapper {
});
}
-
if (agent.getAgentClientRolesList() != null &&
!agent.getAgentClientRolesList().isEmpty()) {
@@ -88,6 +87,7 @@ public class AgentMapper {
});
}
+
persistenceModel.setAgentRole(userRoleSet);
return persistenceModel;
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
index f6fe52d..cb28bb3 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
@@ -22,6 +22,8 @@ package org.apache.custos.sharing;
import brave.Tracing;
import brave.grpc.GrpcTracing;
import io.grpc.ServerInterceptor;
+import org.apache.custos.core.services.commons.ServiceInterceptor;
+import org.apache.custos.sharing.validator.InputValidator;
import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -54,4 +56,15 @@ public class SharingServiceInitializer {
return grpcTracing.newServerInterceptor();
}
+ @Bean
+ public InputValidator getValidator() {
+ return new InputValidator();
+ }
+
+ @Bean
+ @GRpcGlobalInterceptor
+ ServerInterceptor validationInterceptor(InputValidator validator){
+ return new ServiceInterceptor(validator);
+ }
+
}
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityMapper.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityMapper.java
index 2bf3323..0e41080 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityMapper.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityMapper.java
@@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory;
import javax.sql.rowset.serial.SerialBlob;
import java.sql.Blob;
+import java.sql.Date;
import java.sql.SQLException;
public class EntityMapper {
@@ -59,14 +60,17 @@ public class EntityMapper {
perEntity.setDescription(entity.getDescription());
}
- if (entity.getFullText() != null &&
entity.getFullText().trim().equals("")) {
+ if (entity.getFullText() != null &&
!entity.getFullText().trim().equals("")) {
perEntity.setFullText(entity.getFullText());
}
- if (entity.getParentId() != null &&
entity.getParentId().trim().equals("")) {
+ if (entity.getParentId() != null &&
!entity.getParentId().trim().equals("")) {
perEntity.setExternalParentId(entity.getParentId());
}
+ if (entity.getOriginalCreationTime() > 0) {
+ perEntity.setOriginalCreatedTime(new
Date(entity.getOriginalCreationTime()));
+ }
return perEntity;
@@ -90,6 +94,10 @@ public class EntityMapper {
.setType(entity.getEntityType().getId())
.setSharedCount(entity.getSharedCount());
+ if (entity.getExternalParentId() != null) {
+ builder.setParentId(entity.getExternalParentId());
+ }
+
if (entity.getDescription() != null) {
builder.setDescription(entity.getDescription());
}
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityTypeMapper.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityTypeMapper.java
index c5b0a93..a517c26 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityTypeMapper.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/EntityTypeMapper.java
@@ -23,6 +23,8 @@ import org.apache.custos.sharing.persistance.model.EntityType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.sql.Date;
+
public class EntityTypeMapper {
private static final Logger LOGGER =
LoggerFactory.getLogger(EntityTypeMapper.class);
@@ -35,9 +37,13 @@ public class EntityTypeMapper {
type.setName(entityType.getName());
type.setTenantId(tenantId);
type.setExternalId(entityType.getId());
- if (entityType.getDescription() != null &&
entityType.getDescription().trim().equals("")) {
+ if (entityType.getDescription() != null && !
entityType.getDescription().trim().equals("")) {
type.setDescription(entityType.getDescription());
}
+
+ if (entityType.getCreatedAt() > 0 ) {
+ type.setCreatedAt(new Date(entityType.getCreatedAt()));
+ }
return type;
}
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/PermissionTypeMapper.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/PermissionTypeMapper.java
index c698865..ba420da 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/PermissionTypeMapper.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/PermissionTypeMapper.java
@@ -23,6 +23,8 @@ import
org.apache.custos.sharing.persistance.model.PermissionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.sql.Date;
+
public class PermissionTypeMapper {
private static final Logger LOGGER =
LoggerFactory.getLogger(PermissionTypeMapper.class);
@@ -35,9 +37,12 @@ public class PermissionTypeMapper {
type.setName(entityType.getName());
type.setTenantId(tenantId);
type.setExternalId(entityType.getId());
- if (entityType.getDescription() != null &&
entityType.getDescription().trim().equals("")) {
+ if (entityType.getDescription() != null && !
entityType.getDescription().trim().equals("")) {
type.setDescription(entityType.getDescription());
}
+ if (entityType.getCreatedAt() > 0 ) {
+ type.setCreatedAt(new Date(entityType.getCreatedAt()));
+ }
return type;
}
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/SharingMapper.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/SharingMapper.java
index 650aa42..9ea5ba1 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/SharingMapper.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/mapper/SharingMapper.java
@@ -52,7 +52,7 @@ public class SharingMapper {
sharing.setPermissionType(permissionType);
sharing.setAssociatingId(ownerId);
sharing.setAssociatingIdType(ownerType);
- sharing.setInheritedEntity(inheritedEntity);
+ sharing.setInheritedParent(inheritedEntity);
sharing.setTenantId(tenantId);
sharing.setId(id);
return sharing;
@@ -61,14 +61,15 @@ public class SharingMapper {
public static Sharing getNewSharing(Sharing oldSharing, long tenantId,
Entity entity) {
String id = entity.getId() + "_" +
- oldSharing.getInheritedEntity().getId() + "_" +
oldSharing.getAssociatingId() + "_" + oldSharing.getPermissionType().getId() +
"_" + tenantId;
+ oldSharing.getInheritedParent().getId() + "_" +
oldSharing.getAssociatingId() + "_" + oldSharing.getPermissionType().getId() +
"_" + tenantId;
Sharing sharing = new Sharing();
sharing.setSharingType(oldSharing.getSharingType());
sharing.setEntity(entity);
sharing.setPermissionType(oldSharing.getPermissionType());
sharing.setAssociatingId(oldSharing.getAssociatingId());
- sharing.setInheritedEntity(oldSharing.getInheritedEntity());
+ sharing.setAssociatingIdType(oldSharing.getAssociatingIdType());
+ sharing.setInheritedParent(oldSharing.getInheritedParent());
sharing.setTenantId(tenantId);
sharing.setId(id);
return sharing;
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Entity.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Entity.java
index e8f69c8..6bad30f 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Entity.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Entity.java
@@ -71,7 +71,7 @@ public class Entity {
private Date lastModifiedAt;
- @Column(nullable = false)
+ @Column(nullable = true)
@Temporal(TemporalType.TIMESTAMP)
private Date originalCreatedTime;
@@ -88,7 +88,7 @@ public class Entity {
@OneToMany(mappedBy = "entity", cascade = CascadeType.ALL)
private Set<Sharing> sharingSet;
- @OneToMany(mappedBy = "inheritedEntity", cascade = CascadeType.ALL)
+ @OneToMany(mappedBy = "inheritedParent", cascade = CascadeType.ALL)
private Set<Sharing> inheritedSharing;
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Sharing.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Sharing.java
index c1d8560..566da2e 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Sharing.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/model/Sharing.java
@@ -64,14 +64,14 @@ public class Sharing {
private PermissionType permissionType;
- @JoinColumn(name = "entity_id", insertable=false, updatable=false)
+ @JoinColumn(name = "entity_id")
@ManyToOne
private org.apache.custos.sharing.persistance.model.Entity entity;
- @JoinColumn(name = "inherited_parent_id", insertable=false,
updatable=false)
+ @JoinColumn(name = "inherited_parent_id")
@ManyToOne
- private org.apache.custos.sharing.persistance.model.Entity inheritedEntity;
+ private org.apache.custos.sharing.persistance.model.Entity inheritedParent;
public String getAssociatingId() {
@@ -138,12 +138,12 @@ public class Sharing {
this.entity = entity;
}
- public org.apache.custos.sharing.persistance.model.Entity
getInheritedEntity() {
- return inheritedEntity;
+ public org.apache.custos.sharing.persistance.model.Entity
getInheritedParent() {
+ return inheritedParent;
}
- public void
setInheritedEntity(org.apache.custos.sharing.persistance.model.Entity
inheritedEntity) {
- this.inheritedEntity = inheritedEntity;
+ public void
setInheritedParent(org.apache.custos.sharing.persistance.model.Entity
inheritedParent) {
+ this.inheritedParent = inheritedParent;
}
public String getAssociatingIdType() {
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
index ce26798..3ae32a8 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
@@ -26,5 +26,6 @@ import java.util.List;
public interface SearchEntityRepository {
- List<Entity> searchEntities(long tenantId, List<SearchCriteria>
searchCriteria);
+
+ List<Entity> searchEntities(long tenantId, List<SearchCriteria>
searchCriteria);
}
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepositoryImpl.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepositoryImpl.java
index e840fc1..db9a04f 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepositoryImpl.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepositoryImpl.java
@@ -23,6 +23,8 @@ import org.apache.custos.sharing.persistance.model.Entity;
import org.apache.custos.sharing.service.EntitySearchField;
import org.apache.custos.sharing.service.SearchCondition;
import org.apache.custos.sharing.service.SearchCriteria;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
@@ -33,7 +35,9 @@ import java.util.List;
import java.util.Map;
@Repository
-public class SearchEntityRepositoryImpl implements SearchEntityRepository {
+public class SearchEntityRepositoryImpl implements SearchEntityRepository {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(SearchEntityRepositoryImpl.class);
@PersistenceContext
EntityManager entityManager;
@@ -45,7 +49,8 @@ public class SearchEntityRepositoryImpl implements
SearchEntityRepository {
String query = createSQLQuery(searchCriteria, valueMap);
- Query q = entityManager.createNativeQuery(query);
+
+ Query q = entityManager.createNativeQuery(query, Entity.class);
for (String key : valueMap.keySet()) {
q.setParameter(key, valueMap.get(key));
}
@@ -137,8 +142,10 @@ public class SearchEntityRepositoryImpl implements
SearchEntityRepository {
}
}
+ query = query.substring(0, query.length() - 5);
query = query + " ORDER BY E.created_at DESC";
+
return query;
}
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SharingRepository.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SharingRepository.java
index 06b6ef6..c319e4e 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SharingRepository.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SharingRepository.java
@@ -21,7 +21,9 @@ package org.apache.custos.sharing.persistance.repository;
import org.apache.custos.sharing.persistance.model.Sharing;
import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
+import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@@ -31,6 +33,8 @@ public interface SharingRepository extends
JpaRepository<Sharing, String> {
"and s.sharing_type IN ?3", nativeQuery = true)
public List<Sharing> findSharingForEntityOfTenant(long tenantId, String
entityId, List<String> sharingTypes);
+ @Modifying
+ @Transactional
@Query(value = "delete from sharing s where s.tenant_id = ?1 and
s.entity_id = ?2 " +
"and s.sharing_type = ?3", nativeQuery = true)
public void removeGivenCascadingPermissionsForEntity(long tenantId, String
entityId, String sharingType);
@@ -53,14 +57,18 @@ public interface SharingRepository extends
JpaRepository<Sharing, String> {
(long tenantId, String entityId, String permissionTypeId, String
associatingIdType, List<String> sharingList);
- public List<Sharing>
deleteAllByInheritedParentIdAndPermissionTypeIdAndTenantIdAndSharingTypeAssociatingId(
+
+ @Transactional
+ public List<Sharing>
deleteAllByInheritedParentIdAndPermissionTypeIdAndTenantIdAndSharingTypeAndAssociatingId(
String inheritedParentId, String permissionTypeId, long tenantId,
String sharingType, String associatedId);
+
+ @Transactional
public void
deleteAllByEntityIdAndPermissionTypeIdAndAssociatingIdAndTenantIdAndInheritedParentId(
String entityId, String permissionTypeId, String associatingId,
long tenantId, String inheritedParentId);
@Query(value = "select * from sharing s where s.tenant_id = ?1 and
s.entity_id = ?2 " +
- "and s.permission_type_id IN ?3 and s.associating_id_type IN ?4",
nativeQuery = true)
+ "and s.permission_type_id IN ?3 and s.associating_id IN ?4",
nativeQuery = true)
public List<Sharing> findAllSharingOfEntityForGroupsUnderPermissions(long
tenantId, String entityId,
List<String> permissionTypes,
List<String> associatedIds);
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/service/SharingService.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/service/SharingService.java
index b622030..fc87834 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/service/SharingService.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/service/SharingService.java
@@ -114,8 +114,12 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
return;
}
+
org.apache.custos.sharing.persistance.model.EntityType
type =
EntityTypeMapper.createEntityType(request.getEntityType(),
request.getTenantId());
+
+ type.setCreatedAt(optionalEntityType.get().getCreatedAt());
+
entityTypeRepository.save(type);
org.apache.custos.sharing.service.Status status =
org.apache.custos.sharing.service.Status
@@ -301,6 +305,9 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
org.apache.custos.sharing.persistance.model.PermissionType
type =
PermissionTypeMapper.createPermissionType(request.getPermissionType(),
request.getTenantId());
+
+ type.setCreatedAt(optionalEntityType.get().getCreatedAt());
+
permissionTypeRepository.save(type);
org.apache.custos.sharing.service.Status status =
org.apache.custos.sharing.service.Status
@@ -447,13 +454,14 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
internalParentId = entity.getParentId() + "@" + tenantId;
+
Optional<org.apache.custos.sharing.persistance.model.Entity>
optionalEntity = entityRepository.
findById(internalParentId);
if (optionalEntity.isEmpty()) {
String msg = "Cannot find a parent Entity with given Id "
+ entity.getParentId();
LOGGER.error(msg);
-
responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+
responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
return;
}
@@ -465,32 +473,32 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
if (entityType.isEmpty()) {
String msg = "Cannot find a Entity Type with given Id " +
entity.getId();
LOGGER.error(msg);
-
responseObserver.onError(io.grpc.Status.NOT_FOUND.asRuntimeException());
+
responseObserver.onError(io.grpc.Status.NOT_FOUND.withDescription(msg).asRuntimeException());
return;
}
org.apache.custos.sharing.persistance.model.Entity enModel =
EntityMapper.createEntity(entity, tenantId,
entityType.get());
- entityRepository.save(enModel);
+ org.apache.custos.sharing.persistance.model.Entity savedEntity =
entityRepository.save(enModel);
+
Optional<org.apache.custos.sharing.persistance.model.PermissionType>
optionalPermissionType =
permissionTypeRepository.findByExternalIdAndTenantId(Constants.OWNER, tenantId);
if (optionalPermissionType.isPresent()) {
Sharing sharing =
SharingMapper.createSharing(optionalPermissionType.get(),
- enModel, enModel, entity.getOwnerId(), Constants.USER,
Constants.DIRECT_CASCADING, tenantId);
+ savedEntity, savedEntity, entity.getOwnerId(),
Constants.USER, Constants.DIRECT_CASCADING, tenantId);
sharingRepository.save(sharing);
}
if (internalParentId != null) {
- addCascadingPermissionForEntity(enModel, internalParentId,
tenantId);
+ addCascadingPermissionForEntity(savedEntity, internalParentId,
tenantId);
}
- Optional<org.apache.custos.sharing.persistance.model.Entity>
optionalEntity = entityRepository.findById(enModel.getId());
List<String> sharingType = new ArrayList<>();
sharingType.add(Constants.INDIRECT_CASCADING);
@@ -498,12 +506,10 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
enModel.getId(),
optionalPermissionType.get().getId(), sharingType);
- org.apache.custos.sharing.persistance.model.Entity savedOne =
optionalEntity.get();
-
if (sharings != null && sharings.size() > 0) {
- savedOne.setSharedCount(sharings.size());
- entityRepository.save(savedOne);
+ savedEntity.setSharedCount(sharings.size());
+ entityRepository.save(savedEntity);
}
@@ -576,10 +582,12 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
if (oldEntity.getExternalParentId() != null &&
!oldEntity.getExternalParentId().equals(newEntity.getExternalParentId())) {
+
sharingRepository.removeGivenCascadingPermissionsForEntity(tenantId,
internalEntityId, Constants.INDIRECT_CASCADING);
}
+
if (newEntity.getExternalParentId() != null) {
String internalParentId = newEntity.getExternalParentId() +
"@" + tenantId;
addCascadingPermissionForEntity(newEntity, internalParentId,
tenantId);
@@ -595,6 +603,8 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
newEntity.setSharedCount(sharings.size());
}
+ newEntity.setCreatedAt(oldEntity.getCreatedAt());
+
entityRepository.save(newEntity);
org.apache.custos.sharing.service.Status status =
org.apache.custos.sharing.service.Status
@@ -632,12 +642,12 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
if (optionalEntity.isEmpty()) {
org.apache.custos.sharing.service.Status status =
-
org.apache.custos.sharing.service.Status.newBuilder().setStatus(true).build();
+
org.apache.custos.sharing.service.Status.newBuilder().setStatus(false).build();
responseObserver.onNext(status);
responseObserver.onCompleted();
} else {
org.apache.custos.sharing.service.Status status =
-
org.apache.custos.sharing.service.Status.newBuilder().setStatus(false).build();
+
org.apache.custos.sharing.service.Status.newBuilder().setStatus(true).build();
responseObserver.onNext(status);
responseObserver.onCompleted();
}
@@ -733,7 +743,7 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
List<org.apache.custos.sharing.service.Entity> entityList = new
ArrayList<>();
- if (entities != null && entities.isEmpty()) {
+ if (entities != null && !entities.isEmpty()) {
for (org.apache.custos.sharing.persistance.model.Entity entity
: entities) {
entityList.add(EntityMapper.createEntity(entity));
@@ -1147,6 +1157,7 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
if (sharings != null && !sharings.isEmpty()) {
+ LOGGER.info("Sharing s found for entity with Id " +
internalParentId);
for (Sharing sharing : sharings) {
Sharing newShr = SharingMapper.getNewSharing(sharing,
tenantId, entity);
newShr.setSharingType(Constants.INDIRECT_CASCADING);
@@ -1168,7 +1179,8 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
String sharingType) {
List<org.apache.custos.sharing.persistance.model.Entity> entities =
-
entityRepository.findAllByExternalParentIdAndTenantId(entity.getId(), tenantId);
+
entityRepository.findAllByExternalParentIdAndTenantId(entity.getExternalId(),
tenantId);
+
if (entities != null && !entities.isEmpty()) {
for (org.apache.custos.sharing.persistance.model.Entity child :
entities) {
@@ -1177,9 +1189,10 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
child, inheritedEntity, userId, ownerType,
sharingType, tenantId);
sharings.add(sharing);
}
- return getAllSharingForChildEntities(child, inheritedEntity,
userIds, tenantId, permissionType, sharings, ownerType, sharingType);
+ getAllSharingForChildEntities(child, inheritedEntity, userIds,
tenantId, permissionType, sharings, ownerType, sharingType);
}
+ return sharings;
}
return sharings;
}
@@ -1247,7 +1260,6 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
Sharing sharing =
SharingMapper.createSharing(optionalPermissionType.get(),
entityOptional.get(), entityOptional.get(), userId,
ownerType, sharingType, tenantId);
-
sharings.add(sharing);
}
@@ -1260,19 +1272,36 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
}
}
- sharingRepository.saveAll(sharings);
- List<String> checkTypes = new ArrayList<>();
- checkTypes.add(Constants.INDIRECT_CASCADING);
+ List<Sharing> effectiveSharings = new ArrayList<>();
+ if (!sharings.isEmpty()) {
+ sharings.forEach(shr -> {
+ Optional<Sharing> sharing =
sharingRepository.findById(shr.getId());
+ if (sharing.isEmpty()) {
+ effectiveSharings.add(shr);
+ }
+
+ });
- List<Sharing> newSharings =
sharingRepository.findAllByEntityAndSharingTypeAndPermissionType(tenantId,
- internalEntityId, optionalPermissionType.get().getId(),
checkTypes);
- org.apache.custos.sharing.persistance.model.Entity entity =
entityOptional.get();
- if (newSharings != null && newSharings.size() > 0) {
- entity.setSharedCount(newSharings.size());
}
- entityRepository.save(entity);
+
+ if (!effectiveSharings.isEmpty()) {
+ sharingRepository.saveAll(effectiveSharings);
+
+
+ List<String> checkTypes = new ArrayList<>();
+ checkTypes.add(Constants.INDIRECT_CASCADING);
+
+ List<Sharing> newSharings =
sharingRepository.findAllByEntityAndSharingTypeAndPermissionType(tenantId,
+ internalEntityId, optionalPermissionType.get().getId(),
checkTypes);
+ org.apache.custos.sharing.persistance.model.Entity entity =
entityOptional.get();
+ if (newSharings != null && newSharings.size() > 0) {
+ entity.setSharedCount(newSharings.size());
+ }
+
+ entityRepository.save(entity);
+ }
org.apache.custos.sharing.service.Status status =
org.apache.custos.sharing.service.Status
.newBuilder()
@@ -1296,7 +1325,7 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
String internalPermissionType = permissionType + "@" + tenantId;
- List<String> usersList = new ArrayList<>();
+ List<String> usersList = request.getOwnerIdList();
Optional<org.apache.custos.sharing.persistance.model.PermissionType>
optionalPermissionType =
permissionTypeRepository.findById(internalPermissionType);
@@ -1331,6 +1360,8 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
for (String userId : usersList) {
+
+ LOGGER.info("deleting " + userId + ":" + internalEntityId + ":" +
internalPermissionType + ":" + tenantId);
sharingRepository.
deleteAllByEntityIdAndPermissionTypeIdAndAssociatingIdAndTenantIdAndInheritedParentId(
internalEntityId,
@@ -1338,7 +1369,7 @@ public class SharingService extends
org.apache.custos.sharing.service.SharingSer
userId,
tenantId,
internalEntityId);
-
sharingRepository.deleteAllByInheritedParentIdAndPermissionTypeIdAndTenantIdAndSharingTypeAssociatingId(
+
sharingRepository.deleteAllByInheritedParentIdAndPermissionTypeIdAndTenantIdAndSharingTypeAndAssociatingId(
internalEntityId,
internalPermissionType,
tenantId,
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/validator/InputValidator.java
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/validator/InputValidator.java
index 6596b21..e5ea4aa 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/validator/InputValidator.java
+++
b/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/validator/InputValidator.java
@@ -114,11 +114,11 @@ public class InputValidator implements Validator {
throw new MissingParameterException("Entity type not found",
null);
}
if (entityTypeRequest.getEntityType().getId() == null ||
entityTypeRequest.
- getEntityType().getId().equals("")) {
+ getEntityType().getId().trim().equals("")) {
throw new MissingParameterException("Entity type id not
found", null);
}
if (entityTypeRequest.getEntityType().getName() == null ||
entityTypeRequest.
- getEntityType().getName().equals("")) {
+ getEntityType().getName().trim().equals("")) {
throw new MissingParameterException("Entity type name not
found", null);
}
} else {
diff --git
a/custos-core-services/sharing-core-service/src/main/proto/SharingService.proto
b/custos-core-services/sharing-core-service/src/main/proto/SharingService.proto
index e2196d3..168e9ef 100644
---
a/custos-core-services/sharing-core-service/src/main/proto/SharingService.proto
+++
b/custos-core-services/sharing-core-service/src/main/proto/SharingService.proto
@@ -81,12 +81,14 @@ message EntityRequest {
string client_id = 1;
int64 tenant_id = 2;
Entity entity = 3;
+ string client_sec = 4;
}
message EntityTypeRequest {
string client_id = 1;
int64 tenant_id = 2;
EntityType entity_type = 3;
+ string client_sec = 4;
}
@@ -94,6 +96,7 @@ message PermissionTypeRequest {
string client_id = 1;
int64 tenant_id = 2;
PermissionType permission_type = 3;
+ string client_sec = 4;
}
@@ -110,6 +113,7 @@ message SearchRequest {
int32 offset = 4;
int32 limit = 5;
repeated SearchCriteria search_criteria = 6;
+ string client_sec = 7;
}
message PermissionRequest {
@@ -117,6 +121,7 @@ message PermissionRequest {
int64 tenant_id = 2;
Entity entity = 3;
PermissionType permission_type = 4;
+ string client_sec = 5;
}
message SharingRequest {
@@ -126,6 +131,7 @@ message SharingRequest {
PermissionType permission_type = 4;
repeated string owner_id = 5;
bool cascade = 6;
+ string client_sec = 7;
}
message Status {
diff --git
a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/federatedAuthenticationCoreService.properties
b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/federatedAuthenticationCoreService.properties
index 750a9f6..9a7f5e5 100644
---
a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/federatedAuthenticationCoreService.properties
+++
b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/federatedAuthenticationCoreService.properties
@@ -1,3 +1,3 @@
-ciLogon.admin.client.id={{vault_cilogon_id}}
-ciLogon.admin.client.secret={{vault_cilogon_password}}
+ciLogon.admin.client.id=cilogon:/adminClient/22dc117c021f7787a3df8519438d4235/1581020563144
+ciLogon.admin.client.secret=c3o_634Ej3IpLCi98LZAx8JX8TE8WhfRtUSFB1qEPaoBKXblNzdCd6VC8pSCh0-SmWC8Tb729Rs6Mh2nQytL5g
ciLogon.admin.auth.endpoint=https://test.cilogon.org/oauth2/oidc-cm
\ No newline at end of file
diff --git
a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/iamAdminCoreService.properties
b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/iamAdminCoreService.properties
index 88a2717..c9f9865 100644
---
a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/iamAdminCoreService.properties
+++
b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/iamAdminCoreService.properties
@@ -2,8 +2,8 @@ iam.server.client.id=admin-cli
iam.server.truststore.path=/home/ubuntu/keystore/keycloak-client-truststore.pkcs12
iam.server.truststore.password=keycloak
iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
-iam.server.admin.username={{vault_keycloak_username}}
-iam.server.admin.password={{vault_keycloak_password}}
+iam.server.admin.username=keycloak
+iam.server.admin.password=5SocwZ78TEUyyj0R
iam.server.super.admin.realm.id=master
iam.federated.cilogon.authorization.endpoint=https://cilogon.org/authorize
iam.federated.cilogon.token.endpoint=https://cilogon.org/oauth2/token
@@ -18,6 +18,6 @@
end.session.endpoint=https://custos.scigap.org/apiserver/identity-management/v1.
user.info.endpoint=https://custos.scigap.org/apiserver/user-management/v1.0.0/userinfo
jwks_uri=https://custos.scigap.org/apiserver/identity-management/v1.0.0/certs
registration.endpoint=https://custos.scigap.org/apiserver/tenant-management/v1.0.0/oauth2/tenant
-ciLogon.admin.client.id={{vault_cilogon_id}}
-ciLogon.admin.client.secret={{vault_cilogon_secret}}
+ciLogon.admin.client.id=cilogon:/adminClient/22dc117c021f7787a3df8519438d4235/1581020563144
+ciLogon.admin.client.secret=c3o_634Ej3IpLCi98LZAx8JX8TE8WhfRtUSFB1qEPaoBKXblNzdCd6VC8pSCh0-SmWC8Tb729Rs6Mh2nQytL5g
ciLogon.admin.auth.endpoint=https://test.cilogon.org/oauth2/oidc-cm
\ No newline at end of file
diff --git
a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityCoreService.properties
b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityCoreService.properties
index 85d0c2a..2a405b5 100644
---
a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityCoreService.properties
+++
b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/identityCoreService.properties
@@ -31,14 +31,14 @@
user.info.endpoint=https://custos.scigap.org/apiserver/user-management/v1.0.0/us
jwks_uri=https://custos.scigap.org/apiserver/identity-management/v1.0.0/certs
registration.endpoint=https://custos.scigap.org:/apiserver/tenant-management/v1.0.0/oauth2/tenant
iam.server.client.id=admin-cli
-iam.server.admin.username={{vault_keycloak_username}}
-iam.server.admin.password={{vault_keycloak_pasword}}
+iam.server.admin.username=keycloak
+iam.server.admin.password=5SocwZ78TEUyyj0R
iam.server.super.admin.realm.id=master
iam.federated.cilogon.authorization.endpoint=https://cilogon.org/authorize
iam.federated.cilogon.token.endpoint=https://cilogon.org/oauth2/token
iam.federated.cilogon.token.userinfo.endpoint=https://cilogon.org/oauth2/userinfo
iam.federated.cilogon.issuer=https://cilogon.org
iam.federated.cilogon.jwksUri=https://cilogon.org/oauth2/certs
-ciLogon.admin.client.id={{vault_cilogin_username}}
-ciLogon.admin.client.secret={{vault_cilogin_password}}
+ciLogon.admin.client.id=cilogon:/adminClient/22dc117c021f7787a3df8519438d4235/1581020563144
+ciLogon.admin.client.secret=c3o_634Ej3IpLCi98LZAx8JX8TE8WhfRtUSFB1qEPaoBKXblNzdCd6VC8pSCh0-SmWC8Tb729Rs6Mh2nQytL5g
ciLogon.admin.auth.endpoint=https://test.cilogon.org/oauth2/oidc-cm
diff --git
a/custos-core-services/utility-services/custos-configuration-service/src/main/resources/sharingManagementService.properties
b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/sharingManagementService.properties
new file mode 100644
index 0000000..07104cf
--- /dev/null
+++
b/custos-core-services/utility-services/custos-configuration-service/src/main/resources/sharingManagementService.properties
@@ -0,0 +1,34 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+tenant.profile.core.service.dns.name=tenant-profile-core-service.custos.svc.cluster.local
+tenant.profile.core.service.port=7000
+iam.admin.service.dns.name=iam-admin-core-service.custos.svc.cluster.local
+iam.admin.service.port=7000
+credential.store.service.dns.name=credential-store-core-service.custos.svc.cluster.local
+credential.store.service.port=7000
+federated.authentication.service.dns.name=federeted-authentication-core-service.custos.svc.cluster.local
+federated.authentication.service.port=7000
+identity.service.dns.name=identity-core-service.custos.svc.cluster.local
+identity.service.port=7000
+user.profile.core.service.dns.name=user-profile-core-service.custos.svc.cluster.local
+user.profile.core.service.port=7000
+iam.server.url=https://keycloak.custos.scigap.org:31000/auth/
+sharing.core.service.dns.name=sharing-core-service.custos.svc.cluster.local
+sharing.core.service.port=7000
\ No newline at end of file
diff --git
a/custos-integration-services/custos-integration-services-commons/pom.xml
b/custos-integration-services/custos-integration-services-commons/pom.xml
index 644bcac..c7a2bab 100644
--- a/custos-integration-services/custos-integration-services-commons/pom.xml
+++ b/custos-integration-services/custos-integration-services-commons/pom.xml
@@ -46,6 +46,16 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>user-profile-core-service-client-stub</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>iam-admin-core-service-client-stub</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
diff --git
a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
index d77b2ee..b1c9f3a 100644
---
a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
+++
b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/AuthInterceptor.java
@@ -198,6 +198,7 @@ public abstract class AuthInterceptor implements
IntegrationServiceInterceptor {
/**
* Authorize tenant request by checking validity of calling tenant and its
child tenant given by clientId
+ *
* @param headers parentTenant Headers
* @param childClientId childTenant Headers
* @return AuthClaim of child tenant
@@ -220,8 +221,19 @@ public abstract class AuthInterceptor implements
IntegrationServiceInterceptor {
CredentialMetadata metadata =
credentialStoreServiceClient.getCustosCredentialFromClientId(request);
+
+ GetCredentialRequest credentialRequest = GetCredentialRequest
+ .newBuilder()
+ .setOwnerId(metadata.getOwnerId())
+ .setType(Type.IAM).build();
+
+ CredentialMetadata iamCredentials =
credentialStoreServiceClient.getCredential(credentialRequest);
+
AuthClaim childClaim = getAuthClaim(metadata);
+ childClaim.setIamAuthSecret(iamCredentials.getSecret());
+ childClaim.setIamAuthId(iamCredentials.getId());
+
boolean statusValidation =
validateTenantStatus(childClaim.getTenantId());
if (!statusValidation) {
diff --git
a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/MultiTenantAuthInterceptor.java
b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/MultiTenantAuthInterceptor.java
new file mode 100644
index 0000000..0cfb8c3
--- /dev/null
+++
b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/interceptors/MultiTenantAuthInterceptor.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.custos.integration.services.commons.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for authorization of multi tenant middleware requests
+ */
+public abstract class MultiTenantAuthInterceptor extends AuthInterceptor {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(AuthInterceptor.class);
+
+ private CredentialStoreServiceClient credentialStoreServiceClient;
+
+ private TenantProfileClient tenantProfileClient;
+
+ private IdentityClient identityClient;
+
+ public MultiTenantAuthInterceptor(CredentialStoreServiceClient
credentialStoreServiceClient,
+ TenantProfileClient tenantProfileClient,
IdentityClient identityClient) {
+ super(credentialStoreServiceClient, tenantProfileClient,
identityClient);
+ this.credentialStoreServiceClient = credentialStoreServiceClient;
+ this.tenantProfileClient = tenantProfileClient;
+ this.identityClient = identityClient;
+
+ }
+
+
+ public AuthClaim authorize(Metadata headers, String clientId) {
+ if (clientId == null) {
+ return authorize(headers);
+ } else {
+ return
authorizeWithParentChildTenantValidationByBasicAuth(headers, clientId);
+ }
+ }
+}
diff --git
a/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/utils/InterServiceModelMapper.java
b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/utils/InterServiceModelMapper.java
new file mode 100644
index 0000000..9bfeb01
--- /dev/null
+++
b/custos-integration-services/custos-integration-services-commons/src/main/java/org/apache/custos/integration/services/commons/utils/InterServiceModelMapper.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.custos.integration.services.commons.utils;
+
+import org.apache.custos.iam.service.UserAttribute;
+import org.apache.custos.iam.service.UserRepresentation;
+import org.apache.custos.user.profile.service.UserProfile;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class InterServiceModelMapper {
+
+
+ public static UserProfile convert(UserRepresentation representation) {
+ UserProfile.Builder profileBuilder = UserProfile.newBuilder();
+
+ if (representation.getRealmRolesCount() > 0) {
+
profileBuilder.addAllRealmRoles(representation.getRealmRolesList());
+ }
+
+ if (representation.getClientRolesCount() > 0) {
+
profileBuilder.addAllClientRoles(representation.getClientRolesList());
+ }
+
+ if (representation.getAttributesCount() > 0) {
+ List<UserAttribute> attributeList =
representation.getAttributesList();
+ List<org.apache.custos.user.profile.service.UserAttribute>
userAtrList = new ArrayList<>();
+ attributeList.forEach(atr -> {
+ org.apache.custos.user.profile.service.UserAttribute
userAttribute =
+ org.apache.custos.user.profile.service.UserAttribute
+ .newBuilder()
+ .setKey(atr.getKey())
+ .addAllValue(atr.getValuesList())
+ .build();
+
+ userAtrList.add(userAttribute);
+ });
+ profileBuilder.addAllAttributes(userAtrList);
+ }
+
+ profileBuilder.setUsername(representation.getUsername().toLowerCase());
+ profileBuilder.setFirstName(representation.getFirstName());
+ profileBuilder.setLastName(representation.getLastName());
+ profileBuilder.setEmail(representation.getEmail());
+
+ return profileBuilder.build();
+ }
+
+
+}
diff --git a/custos-integration-services/pom.xml
b/custos-integration-services/pom.xml
index 13079bf..627d1aa 100644
--- a/custos-integration-services/pom.xml
+++ b/custos-integration-services/pom.xml
@@ -40,6 +40,7 @@
<module>group-management-service-parent</module>
<module>agent-management-service-parent</module>
<module>resource-secret-management-service-parent</module>
+ <module>sharing-management-service-parent</module>
</modules>
diff --git a/custos-integration-services/pom.xml
b/custos-integration-services/sharing-management-service-parent/pom.xml
similarity index 52%
copy from custos-integration-services/pom.xml
copy to custos-integration-services/sharing-management-service-parent/pom.xml
index 13079bf..75c1b8d 100644
--- a/custos-integration-services/pom.xml
+++ b/custos-integration-services/sharing-management-service-parent/pom.xml
@@ -8,12 +8,12 @@
~ "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
+ ~ 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
+ ~ 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.
-->
@@ -22,25 +22,18 @@
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>custos</artifactId>
+ <artifactId>custos-integration-services</artifactId>
<groupId>org.apache.custos</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
- <artifactId>custos-integration-services</artifactId>
- <packaging>pom</packaging>
- <modules>
- <module>tenant-management-service-parent</module>
- <module>identity-management-service-parent</module>
- <module>custos-integration-services-commons</module>
- <module>user-management-service-parent</module>
-
- <module>scim-service</module>
-
- <module>group-management-service-parent</module>
- <module>agent-management-service-parent</module>
- <module>resource-secret-management-service-parent</module>
+ <artifactId>sharing-management-service-parent</artifactId>
+ <packaging>pom</packaging>
+ <modules>
+ <module>sharing-management-service</module>
+ <module>sharing-management-service-sidecar</module>
</modules>
+
</project>
\ No newline at end of file
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/Dockerfile
b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/Dockerfile
new file mode 100644
index 0000000..6dad233
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/Dockerfile
@@ -0,0 +1,3 @@
+FROM envoyproxy/envoy:v1.14.1
+COPY src/main/resources/sharing-management-service.pb
/data/sharing-management-service.pb
+COPY src/main/resources/envoy.yaml /etc/envoy/envoy.yaml
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/pom.xml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/pom.xml
new file mode 100644
index 0000000..2179362
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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>sharing-management-service-parent</artifactId>
+ <groupId>org.apache.custos</groupId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>sharing-management-service-sidecar</artifactId>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-maven-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/envoy.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/envoy.yaml
new file mode 100644
index 0000000..59a2778
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/envoy.yaml
@@ -0,0 +1,48 @@
+admin:
+ access_log_path: /tmp/admin_access.log
+ address:
+ socket_address: { address: 0.0.0.0, port_value: 9901 }
+
+static_resources:
+ listeners:
+ - name: main-listener
+ address:
+ socket_address: { address: 0.0.0.0, port_value: 50000 }
+ filter_chains:
+ - filters:
+ - name: envoy.http_connection_manager
+ config:
+ stat_prefix: grpc_json
+ codec_type: AUTO
+ route_config:
+ name: local_route
+ virtual_hosts:
+ - name: local_service
+ domains: ["*"]
+ routes:
+ - match: { prefix: "/", grpc: {} }
+ route: { cluster: grpc-backend-services, timeout: {
seconds: 60 } }
+ http_filters:
+ - name: envoy.grpc_json_transcoder
+ config:
+ proto_descriptor: "/data/sharing-management-service.pb"
+ services:
["org.apache.custos.sharing.management.service.SharingManagementService"]
+ convert_grpc_status: true
+ print_options:
+ add_whitespace: true
+ always_print_primitive_fields: true
+ always_print_enums_as_ints: false
+ preserve_proto_field_names: true
+ - name: envoy.router
+
+ clusters:
+ - name: grpc-backend-services
+ connect_timeout: 1.25s
+ type: logical_dns
+ lb_policy: round_robin
+ dns_lookup_family: V4_ONLY
+ http2_protocol_options: {}
+ hosts:
+ - socket_address:
+ address: localhost
+ port_value: 7000
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/sharing-management-service.pb
b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/sharing-management-service.pb
new file mode 100644
index 0000000..227eb2a
Binary files /dev/null and
b/custos-integration-services/sharing-management-service-parent/sharing-management-service-sidecar/src/main/resources/sharing-management-service.pb
differ
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/Dockerfile
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/Dockerfile
new file mode 100644
index 0000000..6457ff8
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/Dockerfile
@@ -0,0 +1,5 @@
+FROM openjdk:11-jre-slim
+VOLUME /tmp
+ARG JAR_FILE
+ADD ${JAR_FILE} app.jar
+ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/pom.xml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/pom.xml
new file mode 100644
index 0000000..9015d9f
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/pom.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you 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>sharing-management-service-parent</artifactId>
+ <groupId>org.apache.custos</groupId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>sharing-management-service</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>tenant-profile-core-service-client-stub</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>iam-admin-core-service-client-stub</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>identity-core-service-client-stub</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>user-profile-core-service-client-stub</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>sharing-core-service-client-stub</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+
<artifactId>federated-authentication-core-service-client-stub</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>credential-store-core-service-client-stubs</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>custos-integration-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.custos</groupId>
+ <artifactId>custos-integration-services-commons</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-actuator</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-starter-config</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-starter-sleuth</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.cloud</groupId>
+ <artifactId>spring-cloud-sleuth-zipkin</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.zipkin.brave</groupId>
+ <artifactId>brave-instrumentation-grpc</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.micrometer</groupId>
+ <artifactId>micrometer-registry-prometheus</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.github.lognet</groupId>
+ <artifactId>grpc-spring-boot-starter</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-stub</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-protobuf</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-netty</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.api.grpc</groupId>
+ <artifactId>proto-google-common-protos</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>com.spotify</groupId>
+ <artifactId>dockerfile-maven-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>com.deviceinsight.helm</groupId>
+ <artifactId>helm-maven-plugin</artifactId>
+ <configuration>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/.helmignore
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/.helmignore
new file mode 100644
index 0000000..50af031
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/.helmignore
@@ -0,0 +1,22 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/Chart.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/Chart.yaml
new file mode 100644
index 0000000..c79c3bf
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm of custos sharing management service
+name: ${artifactId}
+version: ${project.version}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/NOTES.txt
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/NOTES.txt
new file mode 100644
index 0000000..b1a316f
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/NOTES.txt
@@ -0,0 +1,21 @@
+1. Get the application URL by running these commands:
+{{- if .Values.ingress.enabled }}
+{{- range $host := .Values.ingress.hosts }}
+ {{- range .paths }}
+ http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
+ {{- end }}
+{{- end }}
+{{- else if contains "NodePort" .Values.service.type }}
+ export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o
jsonpath="{.spec.ports[0].nodePort}" services {{ include "helm.fullname" . }})
+ export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o
jsonpath="{.items[0].status.addresses[0].address}")
+ echo http://$NODE_IP:$NODE_PORT
+{{- else if contains "LoadBalancer" .Values.service.type }}
+ NOTE: It may take a few minutes for the LoadBalancer IP to be available.
+ You can watch the status of by running 'kubectl get --namespace {{
.Release.Namespace }} svc -w {{ include "helm.fullname" . }}'
+ export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{
include "helm.fullname" . }} --template "{{"{{ range (index
.status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
+ echo http://$SERVICE_IP:{{ .Values.service.port }}
+{{- else if contains "ClusterIP" .Values.service.type }}
+ export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l
"app.kubernetes.io/name={{ include "helm.name" .
}},app.kubernetes.io/instance={{ .Release.Name }}" -o
jsonpath="{.items[0].metadata.name}")
+ echo "Visit http://127.0.0.1:8080 to use your application"
+ kubectl port-forward $POD_NAME 8080:80
+{{- end }}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/_helpers.tpl
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/_helpers.tpl
new file mode 100644
index 0000000..86a9288
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/_helpers.tpl
@@ -0,0 +1,56 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helm.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to
this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "helm.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "helm.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 |
trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Common labels
+*/}}
+{{- define "helm.labels" -}}
+app.kubernetes.io/name: {{ include "helm.name" . }}
+helm.sh/chart: {{ include "helm.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end -}}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helm.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create -}}
+ {{ default (include "helm.fullname" .) .Values.serviceAccount.name }}
+{{- else -}}
+ {{ default "default" .Values.serviceAccount.name }}
+{{- end -}}
+{{- end -}}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/deployment.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/deployment.yaml
new file mode 100644
index 0000000..2fe140f
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/deployment.yaml
@@ -0,0 +1,78 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "helm.fullname" . }}
+ labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+ replicas: {{ .Values.replicaCount }}
+ rollingUpdate:
+ maxSurge: {{ .Values.rollingUpdate.maxSurge }}
+ maxUnavailable: {{ .Values.rollingUpdate.maxUnavailable }}
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: {{ include "helm.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+ template:
+ metadata:
+ annotations:
+ linkerd.io/inject: enabled
+ labels:
+ app.kubernetes.io/name: {{ include "helm.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
+ spec:
+ {{- with .Values.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ template "helm.serviceAccountName" . }}
+ securityContext:
+ {{- toYaml .Values.podSecurityContext | nindent 8 }}
+ containers:
+ - name: {{ .Chart.Name }}
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.service.port }}
+ protocol: TCP
+ - name: grpc
+ containerPort: {{ .Values.service.grpcport }}
+ protocol: TCP
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ - name: {{ .Chart.Name }}-envoy-proxy
+ securityContext:
+ {{- toYaml .Values.securityContext | nindent 12 }}
+ image: {{ .Values.proxy.repository }}:{{ .Values.proxy.tag }}
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ ports:
+ - name: envoyhttp
+ containerPort: {{ .Values.proxy.port }}
+ protocol: TCP
+ - name: adminhttp
+ containerPort: {{ .Values.proxy.adminport }}
+ protocol: TCP
+ readinessProbe:
+ httpGet:
+ path: /actuator/health
+ port: {{ .Values.service.port }}
+ initialDelaySeconds: {{
.Values.readinessProbe.initialDelaySeconds }}
+ periodSeconds: {{ .Values.readinessProbe.periodSeconds }}
+ successThreshold: {{ .Values.readinessProbe.successThreshold }}
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ {{- with .Values.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress-grpc.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress-grpc.yaml
new file mode 100644
index 0000000..3fe743d
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress-grpc.yaml
@@ -0,0 +1,22 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ annotations:
+ kubernetes.io/ingress.class: "nginx"
+ nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
+ cert-manager.io/cluster-issuer: letsencrypt-production
+ name: ${artifactId}-ingress-grpc
+spec:
+ rules:
+ - host: custos.scigap.org
+ http:
+ paths:
+ - path:
/org.apache.custos.sharing.management.service.SharingManagementService(/|$)(.*)
+ backend:
+ serviceName: sharing-management-service
+ servicePort: grpc
+
+ tls:
+ - hosts:
+ - custos.scigap.org
+ secretName: tls-secret
\ No newline at end of file
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress.yaml
new file mode 100644
index 0000000..634f5a8
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/ingress.yaml
@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use
extensions/v1beta1
+kind: Ingress
+metadata:
+ name: ${artifactId}-ingress
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /sharing-management/$2
+ cert-manager.io/cluster-issuer: letsencrypt-production
+spec:
+ rules:
+ - host: custos.scigap.org
+ http:
+ paths:
+ - path: /sharing-management(/|$)(.*)
+ backend:
+ serviceName: sharing-management-service
+ servicePort: envoyhttp
+
+ tls:
+ - hosts:
+ - custos.scigap.org
+ secretName: tls-secret
\ No newline at end of file
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/service.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/service.yaml
new file mode 100644
index 0000000..d1e773a
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/service.yaml
@@ -0,0 +1,33 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "helm.name" . }}
+ annotations:
+ getambassador.io/config: |
+ ---
+ apiVersion: ambassador/v1
+ kind: Mapping
+ name: tenant-management-service-mapping
+ prefix: /tenant-management/
+ rewrite: ""
+ service: tenant-management-service.custos:50000
+ labels:
+{{ include "helm.labels" . | indent 4 }}
+spec:
+ type: {{ .Values.service.type }}
+ ports:
+ - port: {{ .Values.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ - port: {{ .Values.service.grpcport }}
+ targetPort: grpc
+ protocol: TCP
+ name: grpc
+ - port: {{ .Values.proxy.port }}
+ targetPort: envoyhttp
+ protocol: TCP
+ name: envoyhttp
+ selector:
+ app.kubernetes.io/name: {{ include "helm.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/serviceaccount.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/serviceaccount.yaml
new file mode 100644
index 0000000..87c82d5
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/serviceaccount.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ template "helm.serviceAccountName" . }}
+ labels:
+{{ include "helm.labels" . | indent 4 }}
+{{- end -}}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/tests/test-connection.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/tests/test-connection.yaml
new file mode 100644
index 0000000..eac279f
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: "{{ include "helm.fullname" . }}-test-connection"
+ labels:
+{{ include "helm.labels" . | indent 4 }}
+ annotations:
+ "helm.sh/hook": test-success
+spec:
+ containers:
+ - name: wget
+ image: busybox
+ command: ['wget']
+ args: ['{{ include "helm.fullname" . }}:{{ .Values.service.port }}']
+ restartPolicy: Never
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/values.yaml
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/values.yaml
new file mode 100644
index 0000000..292eba6
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/helm/values.yaml
@@ -0,0 +1,84 @@
+# Default values for helm.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 2
+
+image:
+ repository: apachecustos/${artifactId}
+ tag: ${project.version}
+ pullPolicy: Always
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname
template
+ name: ${artifactId}
+
+podSecurityContext: {}
+ # fsGroup: 2000
+
+securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+service:
+ type: ClusterIP
+ port: 8080
+ grpcport: 7000
+
+ingress:
+ enabled: false
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ hosts:
+ - host: chart-example.local
+ paths: []
+
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+resources: {}
+ # We usually recommend not to specify default resources and to leave this as
a conscious
+ # choice for the user. This also increases chances charts run on
environments with little
+ # resources, such as Minikube. If you do want to specify resources,
uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after
'resources:'.
+ # limits:
+ # cpu: 100m
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+proxy:
+ repository: apachecustos/sharing-management-service-sidecar
+ tag: 1.0-SNAPSHOT
+ port: 50000
+ adminport: 9901
+
+rollingUpdate:
+ maxSurge: 1
+ maxUnavailable: 25%
+
+readinessProbe:
+ initialDelaySeconds: 5
+ periodSeconds: 1
+ successThreshold: 1
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/SharingManagementServiceInitializer.java
similarity index 50%
copy from
custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
copy to
custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/SharingManagementServiceInitializer.java
index f6fe52d..7ca3b43 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/SharingServiceInitializer.java
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/SharingManagementServiceInitializer.java
@@ -17,41 +17,64 @@
* under the License.
*/
-package org.apache.custos.sharing;
+package org.apache.custos.sharing.management;
import brave.Tracing;
import brave.grpc.GrpcTracing;
+import io.grpc.ClientInterceptor;
import io.grpc.ServerInterceptor;
+import
org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.integration.core.interceptor.ServiceInterceptor;
+import org.apache.custos.sharing.management.interceptors.AuthInterceptorImpl;
+import org.apache.custos.sharing.management.interceptors.InputValidator;
import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
-import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
-import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+import java.util.Stack;
@SpringBootApplication
-@EnableJpaAuditing
-@EnableJpaRepositories(basePackages = "org.apache.custos")
@ComponentScan(basePackages = "org.apache.custos")
-@EntityScan(basePackages = "org.apache.custos")
-public class SharingServiceInitializer {
+public class SharingManagementServiceInitializer {
public static void main(String[] args) {
- SpringApplication.run(SharingServiceInitializer.class, args);
+ SpringApplication.run(SharingManagementServiceInitializer.class, args);
}
@Bean
public GrpcTracing grpcTracing(Tracing tracing) {
+ // Tracing tracing1 = Tracing.newBuilder().build();
return GrpcTracing.create(tracing);
}
- //grpc-spring-boot-starter provides @GrpcGlobalInterceptor to allow
server-side interceptors to be registered with all
- //server stubs, we are just taking advantage of that to install the
server-side gRPC tracer.
+ //We also create a client-side interceptor and put that in the context,
this interceptor can then be injected into gRPC clients and
+ //then applied to the managed channel.
+ @Bean
+ ClientInterceptor grpcClientSleuthInterceptor(GrpcTracing grpcTracing) {
+ return grpcTracing.newClientInterceptor();
+ }
+
@Bean
@GRpcGlobalInterceptor
ServerInterceptor grpcServerSleuthInterceptor(GrpcTracing grpcTracing) {
return grpcTracing.newServerInterceptor();
}
+ @Bean
+ public Stack<IntegrationServiceInterceptor>
getInterceptorSet(AuthInterceptorImpl authInterceptor,
+
+
InputValidator validator) {
+ Stack<IntegrationServiceInterceptor> interceptors = new Stack<>();
+ interceptors.add(validator);
+ interceptors.add(authInterceptor);
+ return interceptors;
+ }
+
+ @Bean
+ @GRpcGlobalInterceptor
+ ServerInterceptor
validationInterceptor(Stack<IntegrationServiceInterceptor>
integrationServiceInterceptors) {
+ return new ServiceInterceptor(integrationServiceInterceptors);
+ }
+
}
diff --git
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/exceptions/SharingException.java
similarity index 71%
copy from
custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
copy to
custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/exceptions/SharingException.java
index ce26798..1353cbc 100644
---
a/custos-core-services/sharing-core-service/src/main/java/org/apache/custos/sharing/persistance/repository/SearchEntityRepository.java
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/exceptions/SharingException.java
@@ -17,14 +17,12 @@
* under the License.
*/
-package org.apache.custos.sharing.persistance.repository;
+package org.apache.custos.sharing.management.exceptions;
-import org.apache.custos.sharing.persistance.model.Entity;
-import org.apache.custos.sharing.service.SearchCriteria;
+public class SharingException extends RuntimeException {
-import java.util.List;
+ public SharingException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
-public interface SearchEntityRepository {
-
- List<Entity> searchEntities(long tenantId, List<SearchCriteria>
searchCriteria);
}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/AuthInterceptorImpl.java
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/AuthInterceptorImpl.java
new file mode 100644
index 0000000..1c4a274
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/AuthInterceptorImpl.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.custos.sharing.management.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.custos.credential.store.client.CredentialStoreServiceClient;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.integration.core.exceptions.NotAuthorizedException;
+import
org.apache.custos.integration.services.commons.interceptors.MultiTenantAuthInterceptor;
+import org.apache.custos.integration.services.commons.model.AuthClaim;
+import org.apache.custos.sharing.service.*;
+import org.apache.custos.tenant.profile.client.async.TenantProfileClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This validates custos credentials
+ */
+@Component
+public class AuthInterceptorImpl extends MultiTenantAuthInterceptor {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(AuthInterceptorImpl.class);
+
+ private CredentialStoreServiceClient credentialStoreServiceClient;
+
+ public AuthInterceptorImpl(CredentialStoreServiceClient
credentialStoreServiceClient,
+ TenantProfileClient tenantProfileClient,
IdentityClient identityClient) {
+ super(credentialStoreServiceClient, tenantProfileClient,
identityClient);
+ this.credentialStoreServiceClient = credentialStoreServiceClient;
+ }
+
+
+ @Override
+ public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+ AuthClaim authClaim;
+ if (msg instanceof EntityTypeRequest) {
+ EntityTypeRequest req = ((EntityTypeRequest) msg);
+ authClaim = validateAuth(headers, req.getClientId());
+ req = req.toBuilder()
+ .setTenantId(authClaim.getTenantId())
+ .setClientSec(authClaim.getIamAuthSecret())
+ .build();
+ return (ReqT) req;
+ } else if (msg instanceof SearchRequest) {
+ SearchRequest req = ((SearchRequest) msg);
+ authClaim = validateAuth(headers, req.getClientId());
+ req = req.toBuilder()
+ .setTenantId(authClaim.getTenantId())
+ .setClientSec(authClaim.getIamAuthSecret())
+ .build();
+ return (ReqT) req;
+
+ } else if (msg instanceof PermissionTypeRequest) {
+ PermissionTypeRequest req = ((PermissionTypeRequest) msg);
+ authClaim = validateAuth(headers, req.getClientId());
+ req = req.toBuilder()
+ .setTenantId(authClaim.getTenantId())
+ .setClientSec(authClaim.getIamAuthSecret())
+ .build();
+ return (ReqT) req;
+
+ } else if (msg instanceof EntityRequest) {
+ EntityRequest req = ((EntityRequest) msg);
+ authClaim = validateAuth(headers, req.getClientId());
+ req = req.toBuilder()
+ .setTenantId(authClaim.getTenantId())
+ .setClientSec(authClaim.getIamAuthSecret())
+ .build();
+ return (ReqT) req;
+
+ } else if (msg instanceof SharingRequest) {
+ SharingRequest req = ((SharingRequest) msg);
+ authClaim = validateAuth(headers, req.getClientId());
+ req = req.toBuilder()
+ .setTenantId(authClaim.getTenantId())
+ .setClientSec(authClaim.getIamAuthSecret())
+ .build();
+ return (ReqT) req;
+
+ }
+
+ return (ReqT) msg;
+
+ }
+
+
+ private AuthClaim validateAuth(Metadata headers, String clientId) {
+ AuthClaim claim = null;
+ try {
+
+ claim = authorize(headers, clientId);
+ } catch (Exception ex) {
+ LOGGER.error(" Authorizing error " + ex.getMessage());
+ throw new NotAuthorizedException("Request is not authorized", ex);
+ }
+ if (claim == null) {
+ throw new NotAuthorizedException("Request is not authorized",
null);
+ }
+ return claim;
+ }
+
+
+}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/InputValidator.java
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/InputValidator.java
new file mode 100644
index 0000000..44d5085
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/interceptors/InputValidator.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.custos.sharing.management.interceptors;
+
+
+import io.grpc.Metadata;
+import org.apache.custos.integration.core.exceptions.MissingParameterException;
+import
org.apache.custos.integration.core.interceptor.IntegrationServiceInterceptor;
+import org.apache.custos.sharing.service.EntityRequest;
+import org.apache.custos.sharing.service.SharingRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * This class validates the request input parameters
+ */
+@Component
+public class InputValidator implements IntegrationServiceInterceptor {
+
+ private static final Logger LOGGER =
LoggerFactory.getLogger(InputValidator.class);
+
+ /**
+ * Input parameter validater
+ *
+ * @param methodName
+ * @param body
+ * @return
+ */
+ private void validate(String methodName, Object body, Metadata headers) {
+ validationAuthorizationHeader(headers);
+
+ if (methodName.equals("createEntity") ||
methodName.equals("updateEntity")) {
+ if (body instanceof EntityRequest) {
+ EntityRequest request = (EntityRequest) body;
+
+ if (request.getEntity() == null ||
+ request.getEntity().getOwnerId() == null ||
request.getEntity().getOwnerId().equals("")) {
+ throw new MissingParameterException("OwnerId not found",
null);
+ }
+
+ } else {
+ throw new MissingParameterException("Unexpected input type for
method " + methodName, null);
+ }
+
+
+ } else if (methodName.equals("shareEntityWithUsers") ||
methodName.equals("revokeEntitySharingFromUsers")) {
+ if (body instanceof SharingRequest) {
+ SharingRequest request = (SharingRequest) body;
+
+ if (request.getOwnerIdList() == null ||
+ request.getOwnerIdList() == null ||
request.getOwnerIdList().size() == 0) {
+ throw new MissingParameterException("OwnerId not found",
null);
+ }
+
+ } else {
+ throw new MissingParameterException("Unexpected input type for
method " + methodName, null);
+ }
+
+ } else if (methodName.equals("shareEntityWithGroups") ||
methodName.equals("revokeEntitySharingFromGroups")) {
+ if (body instanceof SharingRequest) {
+ SharingRequest request = (SharingRequest) body;
+
+ if (request.getOwnerIdList() == null ||
+ request.getOwnerIdList() == null ||
request.getOwnerIdList().size() == 0) {
+ throw new MissingParameterException("Group Id not found",
null);
+ }
+
+ } else {
+ throw new MissingParameterException("Unexpected input type for
method " + methodName, null);
+ }
+
+ }
+
+ }
+
+
+ @Override
+ public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+ validate(method, msg, headers);
+ return msg;
+ }
+
+
+ private boolean validationAuthorizationHeader(Metadata headers) {
+ if (headers.get(Metadata.Key.of("authorization",
Metadata.ASCII_STRING_MARSHALLER)) == null
+ || headers.get(Metadata.Key.of("Authorization",
Metadata.ASCII_STRING_MARSHALLER)) == null) {
+ throw new MissingParameterException("authorization header not
available", null);
+ }
+
+ return true;
+ }
+
+}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/service/SharingManagementService.java
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/service/SharingManagementService.java
new file mode 100644
index 0000000..bdb9351
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/java/org/apache/custos/sharing/management/service/SharingManagementService.java
@@ -0,0 +1,693 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.custos.sharing.management.service;
+
+import io.grpc.stub.StreamObserver;
+import org.apache.custos.iam.admin.client.IamAdminServiceClient;
+import org.apache.custos.iam.service.CheckingResponse;
+import org.apache.custos.iam.service.UserRepresentation;
+import org.apache.custos.iam.service.UserSearchMetadata;
+import org.apache.custos.iam.service.UserSearchRequest;
+import org.apache.custos.identity.client.IdentityClient;
+import org.apache.custos.identity.service.AuthToken;
+import org.apache.custos.identity.service.GetUserManagementSATokenRequest;
+import
org.apache.custos.integration.services.commons.utils.InterServiceModelMapper;
+import org.apache.custos.sharing.client.SharingClient;
+import org.apache.custos.sharing.management.exceptions.SharingException;
+import
org.apache.custos.sharing.management.service.SharingManagementServiceGrpc.SharingManagementServiceImplBase;
+import org.apache.custos.sharing.service.Status;
+import org.apache.custos.sharing.service.*;
+import org.apache.custos.user.profile.client.UserProfileClient;
+import org.apache.custos.user.profile.service.*;
+import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+
+@GRpcService
+public class SharingManagementService extends SharingManagementServiceImplBase
{
+
+ private static Logger LOGGER =
LoggerFactory.getLogger(SharingManagementService.class);
+
+ @Autowired
+ private UserProfileClient userProfileClient;
+
+ @Autowired
+ private IamAdminServiceClient iamAdminServiceClient;
+
+ @Autowired
+ private SharingClient sharingClient;
+
+ @Autowired
+ private IdentityClient identityClient;
+
+
+ @Override
+ public void createEntityType(EntityTypeRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to createEntityType in tenant " +
request.getTenantId() +
+ " with entity type Id " +
request.getEntityType().getId());
+
+ Status status = sharingClient.createEntityType(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at createEntityType " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void updateEntityType(EntityTypeRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to updateEntityType in tenant " +
request.getTenantId() +
+ " with entity type Id " +
request.getEntityType().getId());
+
+ Status status = sharingClient.updateEntityType(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at updateEntityType " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void deleteEntityType(EntityTypeRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to deleteEntityType in tenant " +
request.getTenantId() +
+ " with entity type Id " +
request.getEntityType().getId());
+
+ Status status = sharingClient.deleteEntityType(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at deleteEntityType " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getEntityType(EntityTypeRequest request,
StreamObserver<EntityType> responseObserver) {
+ try {
+ LOGGER.debug("Request received to getEntityType in tenant " +
request.getTenantId() +
+ " with entity type Id " +
request.getEntityType().getId());
+
+ EntityType type = sharingClient.getEntityType(request);
+ responseObserver.onNext(type);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getEntityType " + ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getEntityTypes(SearchRequest request,
StreamObserver<EntityTypes> responseObserver) {
+ try {
+ LOGGER.debug("Request received to getEntityTypes in tenant " +
request.getTenantId());
+
+ EntityTypes entityTypes = sharingClient.getEntityTypes(request);
+ responseObserver.onNext(entityTypes);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getEntityTypes " + ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void createPermissionType(PermissionTypeRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to createPermissionType in tenant "
+ request.getTenantId() +
+ " with permission id " +
request.getPermissionType().getId());
+
+ Status status = sharingClient.createPermissionType(request);
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at createPermissionType " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void updatePermissionType(PermissionTypeRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to updatePermissionType in tenant "
+ request.getTenantId() +
+ " with permission id " +
request.getPermissionType().getId());
+ Status status = sharingClient.updatePermissionType(request);
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at updatePermissionType " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void deletePermissionType(PermissionTypeRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to deletePermissionType in tenant "
+ request.getTenantId() +
+ " with permission id " +
request.getPermissionType().getId());
+ Status status = sharingClient.deletePermissionType(request);
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at deletePermissionType " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getPermissionType(PermissionTypeRequest request,
StreamObserver<PermissionType> responseObserver) {
+ try {
+ LOGGER.debug("Request received to getPermissionType in tenant " +
request.getTenantId() +
+ " with permission id " +
request.getPermissionType().getId());
+ PermissionType permissionType =
sharingClient.getPermissionType(request);
+ responseObserver.onNext(permissionType);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getPermissionType " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getPermissionTypes(SearchRequest request,
StreamObserver<PermissionTypes> responseObserver) {
+ try {
+ LOGGER.debug("Request received to getPermissionTypes in tenant " +
request.getTenantId());
+ PermissionTypes permissionTypes =
sharingClient.getPermissionTypes(request);
+ responseObserver.onNext(permissionTypes);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getPermissionTypes " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void createEntity(EntityRequest request, StreamObserver<Status>
responseObserver) {
+ try {
+ LOGGER.debug("Request received to createEntity in tenant " +
request.getTenantId() +
+ " with entity id " + request.getEntity().getId());
+
+ long tenantId = request.getTenantId();
+
+ String username = request.getEntity().getOwnerId();
+
+ String clientId = request.getClientId();
+
+ String clientSec = request.getClientSec();
+
+ String profileId = validateAndGetUserProfile(username, clientId,
clientSec, tenantId);
+
+
+ Entity entity = request.getEntity();
+ entity = entity.toBuilder().setOwnerId(profileId).build();
+
+ request = request.toBuilder().setEntity(entity).build();
+
+ Status status = sharingClient.createEntity(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at createEntity " + ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void updateEntity(EntityRequest request, StreamObserver<Status>
responseObserver) {
+ try {
+ LOGGER.debug("Request received to updateEntity in tenant " +
request.getTenantId() +
+ " with entity id " + request.getEntity().getId());
+
+ long tenantId = request.getTenantId();
+
+ String username = request.getEntity().getOwnerId();
+
+ String clientId = request.getClientId();
+
+ String clientSec = request.getClientSec();
+
+ String profileId = validateAndGetUserProfile(username, clientId,
clientSec, tenantId);
+
+
+ Entity entity = request.getEntity();
+ entity = entity.toBuilder().setOwnerId(profileId).build();
+
+ request = request.toBuilder().setEntity(entity).build();
+
+ Status status = sharingClient.updateEntity(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at updateEntity " + ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void isEntityExists(EntityRequest request, StreamObserver<Status>
responseObserver) {
+ try {
+ LOGGER.debug("Request received to isEntityExists in tenant " +
request.getTenantId() +
+ " with entity id " + request.getEntity().getId());
+
+ Status status = sharingClient.isEntityExists(request);
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at isEntityExists " + ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getEntity(EntityRequest request, StreamObserver<Entity>
responseObserver) {
+ try {
+ LOGGER.debug("Request received to getEntity in tenant " +
request.getTenantId() +
+ " with entity Id " + request.getEntity().getId());
+
+ Entity entity = sharingClient.getEntity(request);
+ responseObserver.onNext(entity);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getListOfSharedUsers " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void deleteEntity(EntityRequest request, StreamObserver<Status>
responseObserver) {
+ try {
+ LOGGER.debug("Request received to deleteEntity in tenant " +
request.getTenantId() +
+ " with entity Id " + request.getEntity().getId());
+
+ Status status = sharingClient.deleteEntity(request);
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at deleteEntity " + ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void searchEntities(SearchRequest request, StreamObserver<Entities>
responseObserver) {
+ try {
+ LOGGER.debug("Request received to searchEntities in tenant " +
request.getTenantId());
+
+ Entities entities = sharingClient.searchEntities(request);
+ responseObserver.onNext(entities);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at searchEntities " + ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getListOfSharedUsers(SharingRequest request,
StreamObserver<SharedOwners> responseObserver) {
+ try {
+ LOGGER.debug("Request received to getListOfSharedUsers in tenant "
+ request.getTenantId() +
+ " with entity Id " + request.getEntity().getId());
+
+ SharedOwners owners = sharingClient.getListOfSharedUsers(request);
+ responseObserver.onNext(owners);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getListOfSharedUsers " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getListOfDirectlySharedUsers(SharingRequest request,
StreamObserver<SharedOwners> responseObserver) {
+ try {
+ LOGGER.debug("Request received to getListOfDirectlySharedUsers in
tenant " + request.getTenantId() +
+ " for entity " + request.getEntity().getId());
+
+ SharedOwners owners =
sharingClient.getListOfDirectlySharedUsers(request);
+ responseObserver.onNext(owners);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getListOfDirectlySharedUsers " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getListOfSharedGroups(SharingRequest request,
StreamObserver<SharedOwners> responseObserver) {
+ try {
+ LOGGER.debug("Request received to getListOfSharedGroups in tenant
" + request.getTenantId() +
+ " for entity " + request.getEntity().getId());
+
+ SharedOwners owners = sharingClient.getListOfSharedGroups(request);
+ responseObserver.onNext(owners);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getListOfSharedGroups " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void getListOfDirectlySharedGroups(SharingRequest request,
StreamObserver<SharedOwners> responseObserver) {
+ try {
+ LOGGER.debug("Request received to getListOfDirectlySharedGroups in
tenant " + request.getTenantId() +
+ " for entity " + request.getEntity().getId());
+
+ SharedOwners owners =
sharingClient.getListOfDirectlySharedGroups(request);
+ responseObserver.onNext(owners);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at getListOfDirectlySharedGroups " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void shareEntityWithUsers(SharingRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to shareEntityWithUsers in tenant "
+ request.getTenantId() +
+ " for entity " + request.getEntity().getId());
+
+ long tenantId = request.getTenantId();
+
+ String clientId = request.getClientId();
+
+ String clientSec = request.getClientSec();
+
+ for (String username : request.getOwnerIdList()) {
+
+ validateAndGetUserProfile(username, clientId, clientSec,
tenantId);
+ }
+
+ Status status = sharingClient.shareEntityWithUsers(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at shareEntityWithUsers " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void shareEntityWithGroups(SharingRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to shareEntityWithGroups in tenant
" + request.getTenantId() +
+ " with entity Id " + request.getEntity().getId());
+
+ long tenantId = request.getTenantId();
+
+ for (String groupId : request.getOwnerIdList()) {
+
+ validateAndGetGroupId(groupId, tenantId);
+ }
+
+ Status status = sharingClient.shareEntityWithGroups(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at shareEntityWithGroups " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void revokeEntitySharingFromUsers(SharingRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to revokeEntitySharingFromUsers in
tenant " + request.getTenantId() +
+ " for entity " + request.getEntity().getId());
+
+ long tenantId = request.getTenantId();
+
+ String clientId = request.getClientId();
+
+ String clientSec = request.getClientSec();
+
+ for (String username : request.getOwnerIdList()) {
+
+ validateAndGetUserProfile(username, clientId, clientSec,
tenantId);
+ }
+
+ Status status =
sharingClient.revokeEntitySharingFromUsers(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at revokeEntitySharingFromUsers " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void revokeEntitySharingFromGroups(SharingRequest request,
StreamObserver<Status> responseObserver) {
+ try {
+ LOGGER.debug("Request received to revokeEntitySharingFromGroups in
tenant " + request.getTenantId() +
+ " for entity " + request.getEntity().getId());
+
+ long tenantId = request.getTenantId();
+
+
+ for (String username : request.getOwnerIdList()) {
+
+ validateAndGetGroupId(username, tenantId);
+ }
+
+ Status status =
sharingClient.revokeEntitySharingFromGroups(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at revokeEntitySharingFromGroups " +
ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+ @Override
+ public void userHasAccess(SharingRequest request, StreamObserver<Status>
responseObserver) {
+ try {
+ LOGGER.debug("Request received to userHasAccess in tenant " +
request.getTenantId() +
+ " for entity " + request.getEntity().getId());
+
+ String clientId = request.getClientId();
+
+ String clientSec = request.getClientSec();
+
+ long tenantId = request.getTenantId();
+
+
+ for (String username : request.getOwnerIdList()) {
+
+ validateAndGetUserProfile(username, clientId, clientSec,
tenantId);
+ }
+
+ UserProfile profile =
UserProfile.newBuilder().setUsername(request.getOwnerId(0)).build();
+
+
+ UserProfileRequest userProfileRequest =
UserProfileRequest.newBuilder()
+ .setTenantId(tenantId)
+ .setProfile(profile)
+ .build();
+ GetAllGroupsResponse response =
userProfileClient.getAllGroupsOfUser(userProfileRequest);
+
+ List<Group> groups = response.getGroupsList();
+
+ if (groups != null && !groups.isEmpty()) {
+
+ for (Group group : groups) {
+ request =
request.toBuilder().addOwnerId(group.getId()).build();
+ }
+ }
+
+ Status status = sharingClient.userHasAccess(request);
+
+ responseObserver.onNext(status);
+ responseObserver.onCompleted();
+
+
+ } catch (Exception ex) {
+ String msg = "Error occurred at userHasAccess " + ex.getMessage();
+ LOGGER.error(msg);
+
responseObserver.onError(io.grpc.Status.INTERNAL.withDescription(msg).asRuntimeException());
+ }
+ }
+
+
+ private String validateAndGetUserProfile(String username, String clientId,
String clientSec, long tenantId) {
+
+ GetUserManagementSATokenRequest userManagementSATokenRequest =
GetUserManagementSATokenRequest
+ .newBuilder()
+ .setClientId(clientId)
+ .setClientSecret(clientSec)
+ .setTenantId(tenantId)
+ .build();
+ AuthToken token =
identityClient.getUserManagementSATokenRequest(userManagementSATokenRequest);
+
+ if (token != null && token.getAccessToken() != null) {
+
+ UserSearchMetadata searchMetadata = UserSearchMetadata
+ .newBuilder()
+ .setUsername(username)
+ .build();
+
+ UserSearchRequest searchRequest = UserSearchRequest
+ .newBuilder()
+ .setTenantId(tenantId)
+ .setAccessToken(token.getAccessToken())
+ .setUser(searchMetadata)
+ .build();
+
+ CheckingResponse response =
iamAdminServiceClient.isUserExist(searchRequest);
+ if (!response.getIsExist()) {
+ throw new SharingException("User " + username + " not found",
null);
+ }
+
+ UserProfile userProfile = UserProfile
+ .newBuilder()
+ .setUsername(username)
+ .build();
+
+ UserProfileRequest request = UserProfileRequest
+ .newBuilder()
+ .setProfile(userProfile)
+ .setTenantId(tenantId)
+ .build();
+
+ UserProfile profile = userProfileClient.getUser(request);
+
+ if (profile == null || profile.getUsername() == null ||
profile.getUsername().equals("")) {
+
+ UserRepresentation representation =
iamAdminServiceClient.getUser(searchRequest);
+
+ UserProfile exProfile =
InterServiceModelMapper.convert(representation);
+
+ UserProfileRequest req = UserProfileRequest
+ .newBuilder()
+ .setProfile(exProfile)
+ .setTenantId(tenantId)
+ .build();
+
+ userProfileClient.createUserProfile(req);
+ return exProfile.getUsername();
+
+ }
+
+ return profile.getUsername();
+
+ } else {
+
+ throw new SharingException("User management token not found ",
null);
+ }
+
+
+ }
+
+ private String validateAndGetGroupId(String groupId, long tenantId) {
+
+
+ Group group = Group.newBuilder().setId(groupId).build();
+
+ GroupRequest groupRequest = GroupRequest
+ .newBuilder()
+ .setTenantId(tenantId)
+ .setGroup(group).build();
+
+ Group exGroup = userProfileClient.getGroup(groupRequest);
+
+ if (exGroup == null || exGroup.getId() == null ||
exGroup.getId().equals("")) {
+
+ throw new SharingException("Group with Id " + groupId + " not
found", null);
+ }
+
+ return exGroup.getId();
+
+
+ }
+
+
+}
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/proto/SharingManagementService.proto
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/proto/SharingManagementService.proto
new file mode 100644
index 0000000..74e4ca5
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/proto/SharingManagementService.proto
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ *
+ */
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.custos.sharing.management.service;
+
+import "SharingService.proto";
+import "google/api/annotations.proto";
+
+
+service SharingManagementService {
+
+
+ rpc createEntityType (org.apache.custos.sharing.service.EntityTypeRequest)
returns (org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ post: "/sharing-management/v1.0.0/entity/type"
+ };
+
+ }
+ rpc updateEntityType (org.apache.custos.sharing.service.EntityTypeRequest)
returns (org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ put: "/sharing-management/v1.0.0/entity/type"
+ };
+
+ }
+ rpc deleteEntityType (org.apache.custos.sharing.service.EntityTypeRequest)
returns (org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ delete: "/sharing-management/v1.0.0/entity/type"
+ };
+
+ }
+ rpc getEntityType (org.apache.custos.sharing.service.EntityTypeRequest)
returns (org.apache.custos.sharing.service.EntityType) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/entity/type"
+ };
+
+ }
+ rpc getEntityTypes (org.apache.custos.sharing.service.SearchRequest)
returns (org.apache.custos.sharing.service.EntityTypes) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/entity/types"
+ };
+
+ }
+
+ rpc createPermissionType
(org.apache.custos.sharing.service.PermissionTypeRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ post: "/sharing-management/v1.0.0/permission/type"
+ };
+
+ }
+ rpc updatePermissionType
(org.apache.custos.sharing.service.PermissionTypeRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ put: "/sharing-management/v1.0.0/permission/type"
+ };
+
+ }
+ rpc deletePermissionType
(org.apache.custos.sharing.service.PermissionTypeRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ delete: "/sharing-management/v1.0.0/permission/type"
+ };
+
+ }
+ rpc getPermissionType
(org.apache.custos.sharing.service.PermissionTypeRequest) returns
(org.apache.custos.sharing.service.PermissionType) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/permission/type"
+ };
+
+ }
+ rpc getPermissionTypes (org.apache.custos.sharing.service.SearchRequest)
returns (org.apache.custos.sharing.service.PermissionTypes) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/permission/types"
+ };
+
+ }
+
+ rpc createEntity (org.apache.custos.sharing.service.EntityRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ post: "/sharing-management/v1.0.0/entity"
+ };
+
+ }
+ rpc updateEntity (org.apache.custos.sharing.service.EntityRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ put: "/sharing-management/v1.0.0/entity"
+ };
+
+ }
+ rpc isEntityExists (org.apache.custos.sharing.service.EntityRequest)
returns (org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/entity/existence"
+ };
+
+ }
+ rpc getEntity (org.apache.custos.sharing.service.EntityRequest) returns
(org.apache.custos.sharing.service.Entity) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/entity"
+ };
+
+ }
+ rpc deleteEntity (org.apache.custos.sharing.service.EntityRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ delete: "/sharing-management/v1.0.0/entity"
+ };
+
+ }
+ rpc searchEntities (org.apache.custos.sharing.service.SearchRequest)
returns (org.apache.custos.sharing.service.Entities) {
+ option (google.api.http) = {
+ post: "/sharing-management/v1.0.0/entities"
+ };
+
+ }
+
+
+ rpc getListOfSharedUsers
(org.apache.custos.sharing.service.SharingRequest) returns
(org.apache.custos.sharing.service.SharedOwners) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/users/share"
+ };
+
+ }
+ rpc getListOfDirectlySharedUsers
(org.apache.custos.sharing.service.SharingRequest) returns
(org.apache.custos.sharing.service.SharedOwners) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/users/share/direct"
+ };
+
+ }
+ rpc getListOfSharedGroups
(org.apache.custos.sharing.service.SharingRequest) returns
(org.apache.custos.sharing.service.SharedOwners) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/groups/share"
+ };
+
+ }
+ rpc getListOfDirectlySharedGroups
(org.apache.custos.sharing.service.SharingRequest) returns
(org.apache.custos.sharing.service.SharedOwners) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/groups/share/direct"
+ };
+
+ }
+
+ rpc shareEntityWithUsers
(org.apache.custos.sharing.service.SharingRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ post: "/sharing-management/v1.0.0/users/share"
+ };
+
+ }
+ rpc shareEntityWithGroups
(org.apache.custos.sharing.service.SharingRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ post: "/sharing-management/v1.0.0/groups/share"
+ };
+
+ }
+ rpc revokeEntitySharingFromUsers
(org.apache.custos.sharing.service.SharingRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ delete: "/sharing-management/v1.0.0/users/share"
+ };
+
+ }
+ rpc revokeEntitySharingFromGroups
(org.apache.custos.sharing.service.SharingRequest) returns
(org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ delete: "/sharing-management/v1.0.0/groups/share"
+ };
+
+ }
+ rpc userHasAccess (org.apache.custos.sharing.service.SharingRequest)
returns (org.apache.custos.sharing.service.Status) {
+ option (google.api.http) = {
+ get: "/sharing-management/v1.0.0/entity/user/access"
+ };
+
+ }
+
+}
\ No newline at end of file
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/application.properties
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/application.properties
new file mode 100644
index 0000000..fe296f1
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/application.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+server.port=8080
+grpc.port=7000
+spring.application.name=sharingManagementService
+spring.zipkin.baseUrl=http://149.165.169.49:9411/
+spring.sleuth.sampler.probability=1
+management.security.enabled=false
+management.endpoints.web.exposure.include=*
+management.endpoint.metrics.enabled=true
+spring.main.allow-bean-definition-overriding=true
\ No newline at end of file
diff --git
a/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/bootstrap.properties
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/bootstrap.properties
new file mode 100644
index 0000000..4b7ed78
--- /dev/null
+++
b/custos-integration-services/sharing-management-service-parent/sharing-management-service/src/main/resources/bootstrap.properties
@@ -0,0 +1,22 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+
+spring.cloud.config.uri=http://custos-configuration-service.custos.svc.cluster.local:9000
+#spring.cloud.config.uri=http://localhost:9000
+spring.profiles.active:default