[EAGLE-1055] update policy proto APIs

https://issues.apache.org/jira/browse/EAGLE-1055

Author: Zhao, Qingwen <qingwzhao@apache.org>

Closes #958 from qingwen220/EAGLE-1055.
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/PolicyResource.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/PolicyResource.java
index ce900fd..3b3dba9 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/PolicyResource.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/resource/PolicyResource.java
@@ -20,6 +20,7 @@
 import com.google.common.base.Preconditions;
 import com.google.inject.Inject;
 import org.apache.eagle.alert.engine.coordinator.PolicyDefinition;
+import org.apache.eagle.alert.engine.coordinator.Publishment;
 import org.apache.eagle.alert.engine.interpreter.PolicyValidationResult;
 import org.apache.eagle.alert.metadata.resource.OpResult;
 import org.apache.eagle.common.rest.RESTResponse;
@@ -60,14 +61,96 @@
     }
 
     @POST
-    @Path("/import")
+    @Path("/create")
     @Consumes(MediaType.APPLICATION_JSON)
     @Produces(MediaType.APPLICATION_JSON)
-    public RESTResponse<PolicyEntity> saveAsPolicyProto(PolicyEntity policyEntity) {
-        Preconditions.checkNotNull(policyEntity, "policyProto should not be null");
-        Preconditions.checkNotNull(policyEntity.getDefinition(), "policyDefinition should not be null");
-        Preconditions.checkNotNull(policyEntity.getAlertPublishmentIds(), "alert publisher list should not be null");
+    public RESTResponse<PolicyEntity> saveAsPolicyProto(PolicyEntity policyEntity,
+                                                        @QueryParam("needPolicyCreated") boolean needPolicyCreated) {
+        return RESTResponse.async(() -> {
+            Preconditions.checkNotNull(policyEntity, "entity should not be null");
+            Preconditions.checkNotNull(policyEntity, "policy definition should not be null");
+            Preconditions.checkNotNull(policyEntity.getAlertPublishmentIds(), "alert publisher list should not be null");
 
+            PolicyDefinition policyDefinition = policyEntity.getDefinition();
+            if (needPolicyCreated) {
+                OpResult result = metadataResource.addPolicy(policyDefinition);
+                if (result.code != 200) {
+                    throw new IllegalArgumentException(result.message);
+                }
+                result = metadataResource.addPublishmentsToPolicy(policyDefinition.getName(), policyEntity.getAlertPublishmentIds());
+                if (result.code != 200) {
+                    throw new IllegalArgumentException(result.message);
+                }
+            }
+            return importPolicyProto(policyEntity);
+        }).get();
+    }
+
+    @POST
+    @Path("/create/{policyId}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public RESTResponse<PolicyEntity> saveAsPolicyProto(@PathParam("policyId") String policyId) {
+        return RESTResponse.async(() -> {
+            Preconditions.checkNotNull(policyId, "policyId should not be null");
+            PolicyDefinition policyDefinition = metadataResource.getPolicyById(policyId);
+
+            if (policyDefinition == null) {
+                throw new IllegalArgumentException("policy does not exist: " + policyId);
+            }
+
+            PolicyEntity policyEntity = new PolicyEntity();
+            policyEntity.setDefinition(policyDefinition);
+
+            List<Publishment> alertPublishments = metadataResource.getPolicyPublishments(policyId);
+            if (alertPublishments != null && !alertPublishments.isEmpty()){
+                List<String> alertPublisherIds = new ArrayList<>();
+                for (Publishment publishment : alertPublishments) {
+                    alertPublisherIds.add(publishment.getName());
+                }
+                policyEntity.setAlertPublishmentIds(alertPublisherIds);
+            }
+            return importPolicyProto(policyEntity);
+        }).get();
+    }
+
+    @POST
+    @Path("/export/{site}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public RESTResponse<Boolean> loadPoliciesByProto(List<PolicyEntity> policyProtoList, @PathParam("site") String site) {
+        return RESTResponse.async(() -> exportPolicyProto(policyProtoList, site)).get();
+    }
+
+    @POST
+    @Path("/exportByName/{site}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public RESTResponse<Boolean> loadPoliciesByName(List<String> policyProtoList, @PathParam("site") String site) {
+        return RESTResponse.async(() -> {
+            if (policyProtoList == null || policyProtoList.isEmpty()) {
+                throw new IllegalArgumentException("policyProtoList is null or empty");
+            }
+            List<PolicyEntity> policyEntities = new ArrayList<PolicyEntity>();
+            for (String name : policyProtoList) {
+                PolicyEntity entity = policyEntityService.getByUUIDorName(null, name);
+                if (entity != null) {
+                    policyEntities.add(entity);
+                }
+            }
+            return exportPolicyProto(policyEntities, site);
+        }).get();
+    }
+
+    @DELETE
+    @Path("/{uuid}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public RESTResponse<Boolean> deletePolicyProto(@PathParam("uuid") String uuid) {
+        return RESTResponse.async(() -> policyEntityService.deletePolicyProtoByUUID(uuid)).get();
+    }
+
+    private PolicyEntity importPolicyProto(PolicyEntity policyEntity) {
         PolicyDefinition policyDefinition = policyEntity.getDefinition();
         List<String> inputStreamType = new ArrayList<>();
         String newDefinition = policyDefinition.getDefinition().getValue();
@@ -81,32 +164,14 @@
         policyDefinition.setName(PolicyIdConversions.parsePolicyId(policyDefinition.getSiteId(), policyDefinition.getName()));
         policyDefinition.setSiteId(null);
         policyEntity.setDefinition(policyDefinition);
-
-        return createOrUpdatePolicyProto(policyEntity);
+        return policyEntityService.createOrUpdatePolicyProto(policyEntity);
     }
 
-    @POST
-    @Path("/export/{site}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public RESTResponse<List<PolicyDefinition>> loadPolicyDefinition(List<PolicyEntity> policyProtoList, @PathParam("site") String site) {
-        return RESTResponse.async(() -> exportPolicyDefinition(policyProtoList, site)).get();
-    }
-
-    @DELETE
-    @Path("/{uuid}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public RESTResponse<Boolean> deletePolicyProto(@PathParam("uuid") String uuid) {
-        return RESTResponse.async(() -> policyEntityService.deletePolicyProtoByUUID(uuid)).get();
-    }
-
-    private List<PolicyDefinition> exportPolicyDefinition(List<PolicyEntity> policyProtoList, String site) {
+    private Boolean exportPolicyProto(List<PolicyEntity> policyProtoList, String site) {
         Preconditions.checkNotNull(site, "site should not be null");
         if (policyProtoList == null || policyProtoList.isEmpty()) {
             throw new IllegalArgumentException("policy prototype list is empty or null");
         }
-        List<PolicyDefinition> policies = new ArrayList<>();
         for (PolicyEntity policyProto : policyProtoList) {
             PolicyDefinition policyDefinition = policyProto.getDefinition();
             List<String> inputStreams = new ArrayList<>();
@@ -134,9 +199,8 @@
                     throw new IllegalArgumentException("fail to create policy publisherments: " + result.message);
                 }
             }
-            policies.add(policyDefinition);
         }
-        return policies;
+        return true;
     }
 
 }
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/service/PolicyEntityService.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/service/PolicyEntityService.java
index 3e03251..3cf6611 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/service/PolicyEntityService.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/service/PolicyEntityService.java
@@ -27,7 +27,7 @@
 
     Collection<PolicyEntity> getAllPolicyProto();
 
-    PolicyEntity getPolicyProtoByUUID(String uuid);
+    PolicyEntity getByUUIDorName(String uuid, String name);
 
     boolean deletePolicyProtoByUUID(String uuid);
 
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/service/memory/PolicyEntityServiceMemoryImpl.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/service/memory/PolicyEntityServiceMemoryImpl.java
index 511b648..d4ce85a 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/service/memory/PolicyEntityServiceMemoryImpl.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/main/java/org/apache/eagle/metadata/service/memory/PolicyEntityServiceMemoryImpl.java
@@ -18,6 +18,7 @@
 package org.apache.eagle.metadata.service.memory;
 
 import com.google.common.base.Preconditions;
+import org.apache.eagle.metadata.exceptions.EntityNotFoundException;
 import org.apache.eagle.metadata.model.PolicyEntity;
 import org.apache.eagle.metadata.service.PolicyEntityService;
 
@@ -33,8 +34,14 @@
     }
 
     @Override
-    public PolicyEntity getPolicyProtoByUUID(String uuid) {
-        return policyProtoMap.get(uuid);
+    public PolicyEntity getByUUIDorName(String uuid, String name) {
+        Preconditions.checkArgument(uuid != null || name != null, "Both uuid and name are null");
+        if (uuid != null) {
+            return policyProtoMap.get(uuid);
+        } else {
+            return policyProtoMap.values().stream().filter(o -> o.getName().equals(name)).findAny()
+                    .orElseThrow(() -> new IllegalArgumentException("Policy proto named " + name + " is not found"));
+        }
     }
 
     @Override
diff --git a/eagle-core/eagle-metadata/eagle-metadata-base/src/test/java/org/apache/eagle/metadata/service/TestPolicyEntityServiceMemoryImpl.java b/eagle-core/eagle-metadata/eagle-metadata-base/src/test/java/org/apache/eagle/metadata/service/TestPolicyEntityServiceMemoryImpl.java
index bfcc1cd..0680c5d 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-base/src/test/java/org/apache/eagle/metadata/service/TestPolicyEntityServiceMemoryImpl.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-base/src/test/java/org/apache/eagle/metadata/service/TestPolicyEntityServiceMemoryImpl.java
@@ -45,6 +45,7 @@
         // define publisher list
         List<String> alertPublisherIds = Arrays.asList("slack");
 
+        // create
         PolicyEntity policyEntity = new PolicyEntity();
         policyEntity.setDefinition(policyDefinition);
         policyEntity.setAlertPublishmentIds(alertPublisherIds);
@@ -55,7 +56,10 @@
         Collection<PolicyEntity> policies =  policyEntityService.getAllPolicyProto();
         Assert.assertTrue(policies.size() == 1);
 
-        PolicyEntity entity = policyEntityService.getPolicyProtoByUUID(policies.iterator().next().getUuid());
+        PolicyEntity entity = policyEntityService.getByUUIDorName(policies.iterator().next().getUuid(), null);
+        Assert.assertTrue(entity.equals(policies.iterator().next()));
+
+        entity = policyEntityService.getByUUIDorName(null, "[null]policy1");
         Assert.assertTrue(entity.equals(policies.iterator().next()));
 
         // test update
diff --git a/eagle-core/eagle-metadata/eagle-metadata-jdbc/src/main/java/org/apache/eagle/metadata/store/jdbc/service/PolicyEntityServiceJDBCImpl.java b/eagle-core/eagle-metadata/eagle-metadata-jdbc/src/main/java/org/apache/eagle/metadata/store/jdbc/service/PolicyEntityServiceJDBCImpl.java
index 65e3757..ac6aed8 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-jdbc/src/main/java/org/apache/eagle/metadata/store/jdbc/service/PolicyEntityServiceJDBCImpl.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-jdbc/src/main/java/org/apache/eagle/metadata/store/jdbc/service/PolicyEntityServiceJDBCImpl.java
@@ -42,9 +42,10 @@
     private static final Logger LOGGER = LoggerFactory.getLogger(PolicyEntityServiceJDBCImpl.class);
 
     private static final String selectSql = "SELECT * FROM policy_prototype";
-    private static final String queryByUUID = "SELECT * FROM policy_prototype where uuid = '%s'";
-    private static final String deleteSqlByUUID = "DELETE FROM policy_prototype where uuid = '%s'";
-    private static final String updateSqlByUUID = "UPDATE policy_prototype SET name = ?, definition = ? , alertPublisherIds = ? , createdtime = ? , modifiedtime = ?  where uuid = ?";
+    private static final String queryByUUID = "SELECT * FROM policy_prototype WHERE uuid = '%s'";
+    private static final String queryByUUIDorName = "SELECT * FROM policy_prototype WHERE uuid = ? or name = ?";
+    private static final String deleteSqlByUUID = "DELETE FROM policy_prototype WHERE uuid = '%s'";
+    private static final String updateSqlByUUID = "UPDATE policy_prototype SET name = ?, definition = ? , alertPublisherIds = ? , createdtime = ? , modifiedtime = ?  WHERE uuid = ?";
     private static final String insertSql = "INSERT INTO policy_prototype (name, definition, alertPublisherIds, createdtime, modifiedtime, uuid) VALUES (?, ?, ?, ?, ?, ?)";
 
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@@ -62,11 +63,16 @@
     }
 
     @Override
-    public PolicyEntity getPolicyProtoByUUID(String uuid) {
-        Preconditions.checkNotNull(uuid, "uuid should not be null");
+    public PolicyEntity getByUUIDorName(String uuid, String name) {
+        Preconditions.checkArgument(uuid != null || name != null, "Both uuid and name are null");
         try {
-            return queryService.query(String.format(queryByUUID, uuid), policyEntityMapper).stream()
-                    .findAny().orElseThrow(() -> new EntityNotFoundException("policyProto is not found by uuid"));
+            return queryService.queryWithCond(queryByUUIDorName, o -> {
+                o.setString(1, uuid);
+                o.setString(2, name);
+            }, policyEntityMapper)
+                    .stream()
+                    .findAny()
+                    .orElseThrow(() -> new EntityNotFoundException("policyProto is not found by uuid or name"));
         } catch (Exception e) {
             throw new IllegalArgumentException(e.getMessage(), e);
         }
@@ -87,7 +93,7 @@
     public PolicyEntity update(PolicyEntity policyProto) {
         Preconditions.checkNotNull(policyProto, "Entity should not be null");
         Preconditions.checkNotNull(policyProto.getUuid(), "uuid should not be null");
-        PolicyEntity current = getPolicyProtoByUUID(policyProto.getUuid());
+        PolicyEntity current = getByUUIDorName(policyProto.getUuid(), null);
 
         if (policyProto.getName() != null) {
             current.setName(policyProto.getName());
diff --git a/eagle-core/eagle-metadata/eagle-metadata-jdbc/src/test/java/org/apache/eagle/metadata/store/jdbc/PolicyEntityServiceJDBCImplTest.java b/eagle-core/eagle-metadata/eagle-metadata-jdbc/src/test/java/org/apache/eagle/metadata/store/jdbc/PolicyEntityServiceJDBCImplTest.java
index d68635e..0492bb1 100644
--- a/eagle-core/eagle-metadata/eagle-metadata-jdbc/src/test/java/org/apache/eagle/metadata/store/jdbc/PolicyEntityServiceJDBCImplTest.java
+++ b/eagle-core/eagle-metadata/eagle-metadata-jdbc/src/test/java/org/apache/eagle/metadata/store/jdbc/PolicyEntityServiceJDBCImplTest.java
@@ -58,7 +58,9 @@
         Collection<PolicyEntity> policies =  policyEntityService.getAllPolicyProto();
         Assert.assertTrue(policies.size() == 1);
 
-        PolicyEntity entity = policyEntityService.getPolicyProtoByUUID(policies.iterator().next().getUuid());
+        PolicyEntity entity = policyEntityService.getByUUIDorName(policies.iterator().next().getUuid(), null);
+        Assert.assertTrue(entity.equals(policies.iterator().next()));
+        entity = policyEntityService.getByUUIDorName(null, "[null]policy1");
         Assert.assertTrue(entity.equals(policies.iterator().next()));
 
         // test update