Federation 3.2.2 - Update Params API 62/7662/4
authorraghavan_ak <a.k.raghavan@est.tech>
Thu, 12 Mar 2020 16:58:27 +0000 (16:58 +0000)
committerraghavan_ak <a.k.raghavan@est.tech>
Tue, 31 Mar 2020 13:44:16 +0000 (19:14 +0530)
* Added route to GatewayController: /peer/{peerId}/updateparams
* Added route to FederationController: /updateparams
* GatewayController /peer/{peerId}/updateparams - is used on the supplier's instance to send new parameters to /updateparams on deployed model instance via subscriber /updateparams
* This is critical piece in the continous model training flow

Issue-Id: ACUMOS-3742

Change-Id: I704d5bcfe4fceb7b82b6e69e8e706583ed3de4b0
Signed-off-by: raghavan_ak <a.k.raghavan@est.tech>
16 files changed:
acumos-fgw-client/pom.xml
acumos-fgw-client/src/main/java/org/acumos/federation/client/FederationClient.java
acumos-fgw-client/src/main/java/org/acumos/federation/client/GatewayClient.java
acumos-fgw-client/src/test/java/org/acumos/federation/client/ClientTest.java
docs/developer-guide.rst
docs/release-notes.rst
gateway/pom.xml
gateway/src/main/java/org/acumos/federation/gateway/Application.java
gateway/src/main/java/org/acumos/federation/gateway/Clients.java
gateway/src/main/java/org/acumos/federation/gateway/DeployedModelClient.java [new file with mode: 0644]
gateway/src/main/java/org/acumos/federation/gateway/DeployedModelService.java [new file with mode: 0644]
gateway/src/main/java/org/acumos/federation/gateway/DeployedModelServiceImpl.java [new file with mode: 0644]
gateway/src/main/java/org/acumos/federation/gateway/FederationController.java
gateway/src/main/java/org/acumos/federation/gateway/GatewayController.java
gateway/src/test/java/org/acumos/federation/gateway/FederationControllerTest.java
gateway/src/test/java/org/acumos/federation/gateway/GatewayControllerTest.java

index 598c8dd..9e504fe 100644 (file)
@@ -4,6 +4,7 @@
 Acumos
 ===================================================================================
 Copyright (C) 2019-2020 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+Modifications Copyright (C) 2020 Nordix Foundation.
 ===================================================================================
 This Acumos software file is distributed by AT&T and Tech Mahindra
 under the Apache License, Version 2.0 (the "License");
@@ -27,7 +28,7 @@ limitations under the License.
        </parent>
        <groupId>org.acumos.federation</groupId>
        <artifactId>acumos-fgw-client</artifactId>
-       <version>3.2.1-SNAPSHOT</version>
+       <version>3.2.2-SNAPSHOT</version>
        <name>Federation Gateway Client</name>
        <properties>
                <!-- dependency versions -->
index 11743d1..348136a 100644 (file)
@@ -3,6 +3,7 @@
  * Acumos
  * ===================================================================================
  * Copyright (C) 2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ===================================================================================
  * This Acumos software file is distributed by AT&T and Tech Mahindra
  * under the Apache License, Version 2.0 (the "License");
@@ -21,7 +22,6 @@ package org.acumos.federation.client;
 
 import java.util.List;
 import java.io.InputStream;
-import java.net.URI;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.core.io.ResourceLoader;
@@ -116,6 +116,11 @@ public class FederationClient extends ClientBase {
         */
        public static final String MODEL_DATA = "/modeldata";
 
+       /**
+        * The URI for sending model data from supplier to subscriber.
+        */
+       public static final String UPDATE_PARAMS = "/updateparams";
+
        /**
         * Peer Status Code for Active
         */
@@ -205,6 +210,15 @@ public class FederationClient extends ClientBase {
                return restTemplate.postForObject(MODEL_DATA, modelData, Void.class);
        }
 
+       /**
+        * @param modelData model (json) data payload
+        * @return string response message
+        * @throws RestClientException if remote acumos is not available
+        */
+       public String updateParams(ModelData modelData) throws RestClientException {
+               return restTemplate.postForObject(UPDATE_PARAMS, modelData, JsonResponse.class).getMessage();
+       }
+
        /**
         * Get a list of the server's catalogs.
         *
index b6f5ef6..6566f8c 100644 (file)
@@ -3,6 +3,7 @@
  * Acumos
  * ===================================================================================
  * Copyright (C) 2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ===================================================================================
  * This Acumos software file is distributed by AT&T and Tech Mahindra
  * under the Apache License, Version 2.0 (the "License");
@@ -176,4 +177,13 @@ public class GatewayClient extends ClientBase {
                        throws RestClientException {
                restTemplate.postForObject(PEER_PFX + FederationClient.MODEL_DATA, modelData, Void.class, peerId);
        }
+
+       /**
+        * Send new params to federated model
+        * @param peerId id to send model data to
+        * @param modelData log data for sending to supplier of model
+        */
+       public String updateParams(String peerId, ModelData modelData) throws RestClientException {
+               return restTemplate.postForObject(PEER_PFX + FederationClient.UPDATE_PARAMS, modelData, JsonResponse.class, peerId).getMessage();
+       }
 }
index d1cb2cd..031e194 100644 (file)
@@ -3,6 +3,7 @@
  * Acumos
  * ===================================================================================
  * Copyright (C) 2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ===================================================================================
  * This Acumos software file is distributed by AT&T and Tech Mahindra
  * under the Apache License, Version 2.0 (the "License");
@@ -22,10 +23,12 @@ package org.acumos.federation.client;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.List;
+
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
 import org.junit.Test;
-import org.junit.Before;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertNotNull;
@@ -133,6 +136,39 @@ public class ClientTest {
                                }
        }
 
+       @Test
+       public void testFederationUpdateParams() throws Exception {
+               FederationClient client = new FederationClient("http://localhost:8888", getConfig("acumosa"));
+               (new ClientMocking()).errorOnNoAuth(401, "Unauthorized")
+               .errorOnBadAuth("acumosa", "acumosa", 403, "Forbidden")
+                   .on("POST /updateparams", xq("{ 'content': 'successfully send model data to peer' }"))
+                   .applyTo(client);
+               ObjectMapper objectMapper = new ObjectMapper();
+               ModelData modelData =
+                               objectMapper.readValue("{\"model\": { \"solutionId\": \"UUID\"}}", ModelData.class);
+                               try {
+                                       client.updateParams(modelData);
+                               } catch (Exception e) {
+                                       fail("failed to send model data");
+                               }
+       }
+
+       @Test
+       public void testGatewayUpdateParams() throws Exception {
+               GatewayClient client = new GatewayClient("http://localhost:8888", getConfig("acumosa"));
+               (new ClientMocking()).errorOnNoAuth(401, "Unauthorized")
+               .errorOnBadAuth("acumosa", "acumosa", 403, "Forbidden")
+                   .on("POST /peer/somepeerid/updateparams", xq("{ 'content': 'successfully send model data to peer' }"))
+                   .applyTo(client);
+               ObjectMapper objectMapper = new ObjectMapper();
+               ModelData modelData =
+                               objectMapper.readValue("{\"model\": { \"solutionId\": \"UUID\"}}", ModelData.class);
+                               try {
+                                       client.updateParams("somepeerid", modelData);
+                               } catch (Exception e) {
+                                       fail("failed to send model data");
+                               }
+       }
 
        @Test
        public void testFederation() throws Exception {
index 2f214a4..5baee72 100644 (file)
@@ -2,6 +2,7 @@
 .. Acumos CC-BY-4.0
 .. ===================================================================================
 .. Copyright (C) 2017-2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+.. Modifications Copyright (C) 2020 Nordix Foundation.
 .. ===================================================================================
 .. This Acumos documentation file is distributed by AT&T and Tech Mahindra
 .. under the Creative Commons Attribution 4.0 International License (the "License");
@@ -130,3 +131,7 @@ The following endpoints are defined on the public "E5" interface:
 * /modeldata
 
   Sends model data to supplier of the model.
+
+* /updateparams
+
+  Sends parameters to deployed models.
index e40bf93..e36172b 100644 (file)
@@ -2,6 +2,7 @@
 .. Acumos CC-BY-4.0
 .. ===================================================================================
 .. Copyright (C) 2017-2020 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+.. Modifications Copyright (C) 2020 Nordix Foundation.
 .. ===================================================================================
 .. This Acumos documentation file is distributed by AT&T and Tech Mahindra
 .. under the Creative Commons Attribution 4.0 International License (the "License");
@@ -23,6 +24,10 @@ Federation Gateway Release Notes
 This server is available as a Docker image in a Docker registry at the Linux Foundation.
 The image name is "federation-gateway" and the tag is a version string as shown below.
 
+Version 3.2.2, 2020-03-24
+-------------------------
+* Adding support for updating params to deployed model (`ACUMOS-3742 <https://jira.acumos.org/browse/ACUMOS-3742>`_)
+
 Version 3.2.1, 2020-03-12
 -------------------------
 * LicenseAsset support NexusArtifactClient - `ACUMOS-3960 <https://jira.acumos.org/browse/ACUMOS-3960>`_
index 50d59e6..7f6f3d8 100644 (file)
@@ -4,6 +4,7 @@
        Acumos
        ===================================================================================
        Copyright (C) 2017-2020 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+       Modifications Copyright (C) 2020 Nordix Foundation.
        ===================================================================================
        This Acumos software file is distributed by AT&T and Tech Mahindra
        under the Apache License, Version 2.0 (the "License");
@@ -27,7 +28,7 @@
        </parent>
        <groupId>org.acumos.federation</groupId>
        <artifactId>gateway</artifactId>
-       <version>3.2.1-SNAPSHOT</version>
+       <version>3.2.2-SNAPSHOT</version>
        <name>Federation Gateway</name>
        <description>Federated Acumos Interface for inter-acumos communication</description>
        <properties>
index 563eb37..96da6ad 100644 (file)
@@ -3,6 +3,7 @@
  * Acumos
  * ===================================================================================
  * Copyright (C) 2017-2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ===================================================================================
  * This Acumos software file is distributed by AT&T and Tech Mahindra
  * under the Apache License, Version 2.0 (the "License");
@@ -203,6 +204,10 @@ public class Application {
                return new LogstashServiceImpl();
        }
 
+       @Bean
+       DeployedModelService deployedModelService() {
+               return new DeployedModelServiceImpl();
+       }
 
        static Docket getApi() {
                String version = Application.class.getPackage().getImplementationVersion();
index 8eabfed..9888e0e 100644 (file)
@@ -101,6 +101,18 @@ public class Clients {
                return new FederationClient(url, federation);
        }
 
+       /**
+        * Create DeployedModelClient for Deployed model solution
+        * @param url model ingress url
+        */
+       public DeployedModelClient getDeployedModelClient(String url) {
+               /*
+                * The target deployedModel can change on request to request basis
+                */
+               ClientConfig cc = new ClientConfig();
+               return new DeployedModelClient(url, cc);
+       }
+
        public synchronized ICommonDataServiceRestClient getCDSClient() {
                if (cdsClient == null) {
                        String url = cdmsConfig.getUrl();
diff --git a/gateway/src/main/java/org/acumos/federation/gateway/DeployedModelClient.java b/gateway/src/main/java/org/acumos/federation/gateway/DeployedModelClient.java
new file mode 100644 (file)
index 0000000..372a1dc
--- /dev/null
@@ -0,0 +1,75 @@
+/*-
+ * ===============LICENSE_START=======================================================
+ * Acumos
+ * ===================================================================================
+ * Copyright (C) 2020 Nordix Foundation
+ * ===================================================================================
+ * This Acumos software file is distributed by Nordix Foundation
+ * 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
+ *
+ * This file 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.
+ * ===============LICENSE_END=========================================================
+ */
+package org.acumos.federation.gateway;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.acumos.federation.client.ClientBase;
+import org.acumos.federation.client.config.ClientConfig;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.web.client.RestClientException;
+
+import java.util.Collections;
+
+
+/**
+ * Client for the DeployedModel API.  Note that servers
+ * implementing the API may restrict what information they
+ * share with clients.  Servers may refuse access to some clients, may refuse
+ * access to some operations, may restrict what data is visible to clients,
+ * etc., based on their particular policies.  This may result in client
+ * methods returning null, returning lists with reduced numbers of elements, or
+ * throwing {@link RestClientException} or its
+ * subclasses.
+ *
+ */
+public class DeployedModelClient extends ClientBase {
+       /**
+        * The URI for to update model params in model.
+        */
+       public static final String MODEL_UPDATE_PARAMS = "/model/methods/updateParams";
+       private HttpHeaders headers = new HttpHeaders();
+
+
+       /**
+        * Create a DeployedModelClient with the default mapper and resource loader.
+        *
+        * @param target The base URL for the server to be accessed.
+        * @param conf   The configuration for certificates and credentials.
+        */
+       public DeployedModelClient(String target, ClientConfig conf) {
+               super(target, conf, null, null);
+               this.headers.setContentType(MediaType.APPLICATION_JSON);
+               this.headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
+       }
+
+       /**
+        * Update params to a deployed model
+        *
+        * @param params The params to be passed on the deployed model
+        */
+       public void updateModelParams(JsonNode params) throws RestClientException{
+               //Using the json API for Deployed models
+               HttpEntity<JsonNode> entity = new HttpEntity<>(params, this.headers);
+               restTemplate.postForObject(MODEL_UPDATE_PARAMS, entity, JsonNode.class);
+       }
+
+}
diff --git a/gateway/src/main/java/org/acumos/federation/gateway/DeployedModelService.java b/gateway/src/main/java/org/acumos/federation/gateway/DeployedModelService.java
new file mode 100644 (file)
index 0000000..bffe89b
--- /dev/null
@@ -0,0 +1,41 @@
+/*-
+ * ===============LICENSE_START=======================================================
+ * Acumos
+ * ===================================================================================
+ * Copyright (C) 2020 Nordix Foundation
+ * ===================================================================================
+ * This Acumos software file is distributed by Nordix Foundation
+ * 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
+ *
+ * This file 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.
+ * ===============LICENSE_END=========================================================
+ */
+package org.acumos.federation.gateway;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.acumos.federation.client.data.ModelData;
+import org.springframework.web.client.RestClientException;
+
+import java.io.IOException;
+
+/**
+ * API for sending model data to Deployed solution model
+ *
+ * Provides a service that will send model data to Deployed solution model
+ */
+public interface DeployedModelService {
+       /**
+        * Send the params to all deployed models
+        *
+        * @param payload ModelData payload
+        *
+        */
+       public String updateParamsForAllDeployments(ModelData payload) throws IOException;
+}
diff --git a/gateway/src/main/java/org/acumos/federation/gateway/DeployedModelServiceImpl.java b/gateway/src/main/java/org/acumos/federation/gateway/DeployedModelServiceImpl.java
new file mode 100644 (file)
index 0000000..79efc0c
--- /dev/null
@@ -0,0 +1,111 @@
+/*-
+ * ===============LICENSE_START=======================================================
+ * Acumos
+ * ===================================================================================
+ * Copyright (C) 2020 Nordix Foundation
+ * ===================================================================================
+ * This Acumos software file is distributed by Nordix Foundation
+ * 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
+ *
+ * This file 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.
+ * ===============LICENSE_END=========================================================
+ */
+package org.acumos.federation.gateway;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.acumos.cds.client.ICommonDataServiceRestClient;
+import org.acumos.cds.domain.MLPSolutionDeployment;
+import org.acumos.federation.client.config.ClientConfig;
+import org.acumos.federation.client.data.ModelData;
+import org.acumos.federation.client.data.ModelInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.client.RestClientException;
+
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.util.List;
+
+public class DeployedModelServiceImpl implements DeployedModelService {
+       private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+       @Autowired
+       private Clients clients;
+
+       private void updateModelParams(String ingressUrl, JsonNode params) throws RestClientException{
+               DeployedModelClient deployedModelClient = clients.getDeployedModelClient(ingressUrl);
+               deployedModelClient.updateModelParams(params);
+       }
+
+       @Override
+       public String updateParamsForAllDeployments(ModelData payload) throws IOException {
+               ModelInfo modelInfo = payload.getModel();
+
+               List<MLPSolutionDeployment> mlpSolutionDeployments = Application.cdsAll(pr -> clients.getCDSClient()
+                   .getSolutionDeployments(modelInfo.getSolutionId(), modelInfo.getRevisionId(), pr));
+               int totalFailure = 0;
+               for (MLPSolutionDeployment mlpSolutionDeployment : mlpSolutionDeployments) {
+                       boolean isUpdateSuccess = updateParamsForDeployment(payload, mlpSolutionDeployment);
+                       if (!isUpdateSuccess){
+                               totalFailure++;
+                       }
+               }
+               String responseMessage="";
+               if(totalFailure > 0){
+                       responseMessage = String.format("Params data posted to deployed models,of total {} " +
+                           "deployments failed posting to {} deployments",mlpSolutionDeployments.size(),totalFailure);
+               }else {
+                       responseMessage = String.format("Params data posted to deployed models, total {} deployments updated", mlpSolutionDeployments.size());
+               }
+               return responseMessage;
+       }
+
+       private boolean updateParamsForDeployment(ModelData payload, MLPSolutionDeployment mlpSolutionDeployment) throws IOException {
+               ObjectMapper objectMapper = new ObjectMapper();
+               JsonNode detailObject = objectMapper.readTree(mlpSolutionDeployment.getDetail());
+               String ingressUrlFieldName = "nodePortUrl";
+               boolean isContinousTrainingEnabled = detailObject != null;
+               if (isContinousTrainingEnabled) {
+                       String continuousTrainingEnabledFieldName = "continuousTrainingEnabled";
+                       isContinousTrainingEnabled = detailObject.has(ingressUrlFieldName)
+                           && detailObject.has(continuousTrainingEnabledFieldName)
+                           && detailObject.get(continuousTrainingEnabledFieldName).asBoolean();
+               }
+
+               if (isContinousTrainingEnabled) {
+                       log.debug("detail object : " + mlpSolutionDeployment.getDetail());
+                       JsonNode deploymentUrl = detailObject.get(ingressUrlFieldName);
+                       log.debug("deployment url" + deploymentUrl.asText());
+                       String ingressUrl = deploymentUrl.asText();
+                       JsonNode params = objectMapper.createObjectNode();
+                       ((ObjectNode) params).set("params", payload.getValue());
+                       try {
+                               updateModelParams(ingressUrl, params);
+                               log.info("successfully posted params to deployment with deployment id {} , solution id {} " +
+                                                               ", revision id {}",
+                                   mlpSolutionDeployment.getDeploymentId(),
+                                   mlpSolutionDeployment.getSolutionId(),
+                                   mlpSolutionDeployment.getRevisionId());
+                       } catch (Exception e) {
+                               log.error("Failed posting params to deployment with deployment id {} , solution id {} " +
+                                                               ", revision id {}",
+                                   mlpSolutionDeployment.getDeploymentId(),
+                                   mlpSolutionDeployment.getSolutionId(),
+                                   mlpSolutionDeployment.getRevisionId());
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+}
\ No newline at end of file
index d58658e..d0c9229 100644 (file)
@@ -3,6 +3,7 @@
  * Acumos
  * ===================================================================================
  * Copyright (C) 2017-2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ===================================================================================
  * This Acumos software file is distributed by AT&T and Tech Mahindra
  * under the Apache License, Version 2.0 (the "License");
@@ -19,6 +20,7 @@
  */
 package org.acumos.federation.gateway;
 
+import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.util.concurrent.Callable;
 import java.util.List;
@@ -92,6 +94,9 @@ public class FederationController {
        @Autowired
        private ContentService contentService;
 
+       @Autowired
+       private DeployedModelService deployedModelService;
+
        private UriTemplateHandler originBuilder;
 
        private String makeOrigin(String uri, Object... params) {
@@ -345,9 +350,10 @@ public class FederationController {
        }
 
        /**
+        * Training API 2: ModelData(receiver)
         * Receives model data payload from
         * {@link GatewayController#peerModelData(HttpServletResponse, ModelData, String)}
-        *
+        * 
         * @param payload         model data payload The payload must have a model.solutionId
         * 
         * @param theHttpResponse HttpServletResponse
@@ -366,4 +372,33 @@ public class FederationController {
                log.debug("Model parameters: {}", payload);
                logstashService.sendModelData(payload);
        }
+
+       /**
+        * Training API 4: UpdateParamA(receiver)
+        * Receives model data payload from
+        * {@link GatewayController#peerModelData(HttpServletResponse, ModelData, String)}
+        *
+        * @param payload         model data payload The payload must have a model.solutionId , model.revisionId
+        * @param theHttpResponse HttpServletResponse
+        * @return success message in JSON format
+        *
+        * @throws IOException
+        */
+       @CrossOrigin
+       @Secured(Security.ROLE_PEER)
+       @ApiOperation(value = "Invoked by Peer Acumos to post model data to Deployed solution model .", response = JsonResponse.class)
+       @PostMapping(FederationClient.UPDATE_PARAMS)
+       @ResponseBody
+       public JsonResponse<String> updateParams(@RequestBody ModelData payload, HttpServletResponse theHttpResponse) throws IOException {
+
+               log.debug(FederationClient.UPDATE_PARAMS);
+
+               log.debug("Model parameters: {}", payload);
+               JsonResponse<String> response = new JsonResponse<String>();
+
+               String responseMessage = deployedModelService.updateParamsForAllDeployments(payload);
+
+               response.setMessage(responseMessage);
+               return response;
+       }
 }
index f4e0aa2..7d2412c 100644 (file)
@@ -3,6 +3,7 @@
  * Acumos
  * ===================================================================================
  * Copyright (C) 2017-2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ===================================================================================
  * This Acumos software file is distributed by AT&T and Tech Mahindra
  * under the Apache License, Version 2.0 (the "License");
@@ -163,6 +164,7 @@ public class GatewayController {
        }
        /**
         * Receives incoming log message from logstash and Sends to {@link FederationController#receiveModelData(ModelData, HttpServletResponse)}
+        * Training API 1: PeerModelData(sender)
         *
         * @param payload model data payload The payload must have a model.solutionId
         *
@@ -214,6 +216,26 @@ public class GatewayController {
 
        }
 
+       /**
+        * Receives incoming log message from logstash and Sends to {@link FederationController#updateParams(ModelData, HttpServletResponse)} (ModelData, HttpServletResponse)}
+        * Training API 3: PeerUpdateParams(sender)
+        *
+        * @param payload         model data payload The payload must have a model.solutionId
+        * @param theHttpResponse HttpServletResponse
+        * @param peerId   PeerID from url path param or USE_SOLUTION_SOURCE to lookup peer based on model.solutionId field
+        * @return success message in JSON formatm
+        */
+       @Secured(Security.ROLE_PEER)
+       @ApiOperation(
+          value = "Invoked by local Acumos to post incoming model data to respective remote peer Acumos instance .",
+          response = String.class)
+       @PostMapping(FederationClient.UPDATE_PARAMS)
+       @ResponseBody
+       public JsonResponse<String> updateParams(HttpServletResponse theHttpResponse, @RequestBody ModelData payload, @PathVariable("peerId") String peerId) {
+               log.debug("peer/{}/updateparams  payload: {}", peerId, payload);
+               return callPeer(theHttpResponse, peerId, peer -> peer.updateParams(payload));
+       }
+
        private JsonResponse getSuccessResponse(
                HttpServletResponse theHttpResponse,
                String message) {
index 9becffa..2cea676 100644 (file)
@@ -3,6 +3,7 @@
  * Acumos
  * ===================================================================================
  * Copyright (C) 2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ===================================================================================
  * This Acumos software file is distributed by AT&T and Tech Mahindra
  * under the Apache License, Version 2.0 (the "License");
@@ -177,6 +178,10 @@ public class FederationControllerTest {
                    .on("GET /solution/ignored/revision/altrevid", xq("{ 'solutionId': 'somesolid', 'revisionId': 'altrevid' }"))
                    .on("GET /revision/altrevid/artifact", xq("[ { 'artifactId': 'altart1', 'artifactTypeCode': 'DI', 'version': 'aa1ver', 'uri': 'host:999/xxx/stuff:aa1ver' }, { 'artifactId': 'altart2', 'artifactTypeCode': 'DI', 'version': 'aa2ver', 'uri': 'someimagename' }]"))
                    .on("GET /revision/altrevid/catalog/somecatid/document", xq("[ { 'documentId': 'altdoc1', 'version': 'ad1ver', 'uri': 'somepath/ad1name/ua/ad1name-ua.ad1type' }, { 'documentId': 'altdoc2', 'version': 'ad2ver', 'uri': 'somepath/ad2name/ua/ad2name.ad2type' }]"))
+                   .on("GET /solution/UUID_SOLUTION/revision/UUID_REVISION/deploy?page=0&size=100", xq("{'content':[{'solutionId':'UUID_SOLUTION'," +
+                                       "'revisionId':'UUID_REVISION','detail':\"{\\\"nodePortUrl\\\":\\\"https://acumos.org:1234\\\",\\\"continuousTrainingEnabled\\\":\\\"true\\\"}\"}]," +
+                                       "'pageable':{'sort':{'sorted':false,'unsorted':true,'empty':true}," +
+                                       "'pageSize':20,'pageNumber':0,'offset':0,'paged':true,'unpaged':false},'totalPages':1,'totalElements':2,'last':true,'first':true,'size':20}"))
                    .applyTo(cdsClient);
 
                when(clients.getCDSClient()).thenReturn(cdsClient);
@@ -344,6 +349,20 @@ public class FederationControllerTest {
                }
        }
 
+       @Test
+       public void testUpdateParams() throws Exception {
+               FederationClient self = new FederationClient("https://localhost:" + port, getConfig("acumosa"));
+
+               ObjectMapper objectMapper = new ObjectMapper();
+               ModelData payloadObjectNode =  objectMapper.readValue("{\"model\": { \"solutionId\": \"UUID_SOLUTION\",\"revisionId\": \"UUID_REVISION\"}}", ModelData.class);
+               try {
+                       self.updateParams(payloadObjectNode);
+               } catch (Exception e) {
+                       System.err.println(e);
+                       fail("exception when sending model data not expected");
+               }
+       }
+
 
        @Test
        public void testSwagger() throws Exception {
index c6290c4..6354cb4 100644 (file)
@@ -3,6 +3,7 @@
  * Acumos
  * ===================================================================================
  * Copyright (C) 2019 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
+ * Modifications Copyright (C) 2020 Nordix Foundation.
  * ===================================================================================
  * This Acumos software file is distributed by AT&T and Tech Mahindra
  * under the Apache License, Version 2.0 (the "License");
@@ -348,6 +349,39 @@ public class GatewayControllerTest {
                }
        }
 
+       @Test
+       public void testUpdateParamsWithPeer() throws Exception {
+               GatewayClient self = new GatewayClient("https://localhost:" + port, getConfig("acumosa"));
+
+               ICommonDataServiceRestClient cdsClient =
+                   CommonDataServiceRestClientImpl.getInstance("http://cds:999",
+                                               ClientBase.buildRestTemplate("http://cds:999", new ClientConfig(), null, null));
+               String peerUrl = "https://somepeer.org:999";
+
+               (new ClientMocking())
+                   .on("GET /peer/peerid", xq("{ 'peerId': 'peerid', 'apiUrl': \'" + peerUrl + "\'}"))
+                   .on("GET /solution/cat2soln", xq("{ 'solutionId': 'cat2soln', 'sourceId': 'peerid' }"))
+                   .on("GET /peer/search?subjectName=gateway.acumosa.org&_j=a&page=0&size=100", xq("{ 'content': [ {'peerId': 'acumosa', 'subjectName': 'gateway.acumosa.org', 'statusCode': 'AC', 'self': true } ], 'last': true, 'number': 0, 'size': 100, 'numberOfElements': 1 }"))
+                   .on("GET /peer/SUBSCIBER_PEER_ID", xq("{'apiUrl':'http://peer.company.com/api','contact1':'SysAdmin212-555-1212','created':'2018-12-16T12:34:56.789Z','description':'string','local':true,'modified':'2018-12-16T12:34:56.789Z','name':'MyPeerName','peerId':'USE_SOLUTION_SOURCE','self':true,'statusCode':'AC','subjectName':'peer.company.com','webUrl':'string'}"))
+                   .applyTo(cdsClient);
+               when(clients.getCDSClient()).thenReturn(cdsClient);
+
+               FederationClient fedClient = new FederationClient(peerUrl, new ClientConfig());
+               (new ClientMocking())
+                   .on("POST /updateparams", xq("{'message': 'successfully posted model data'}"))
+                   .applyTo(fedClient);
+               when(clients.getFederationClient(any(String.class))).thenReturn(fedClient);
+
+               ObjectMapper objectMapper = new ObjectMapper();
+               ModelData payloadObjectNode =
+                   objectMapper.readValue("{\"model\": { \"solutionId\": \"cat2soln\"}}", ModelData.class);
+               try {
+                       self.updateParams("SUBSCIBER_PEER_ID", payloadObjectNode);
+               } catch (Exception e) {
+                       fail("was not able to send modeldata to peer");
+               }
+       }
+
 
        @Test
        public void testSwagger() throws Exception {