26e9f899a6480eb787978564146ed6b62716e494
[appc.git] / appc-sequence-generator / appc-sequence-generator-bundle / src / main / java / org / onap / appc / seqgen / provider / SequenceGeneratorProvider.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APP-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property.  All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.appc.seqgen.provider;
22
23 import com.att.eelf.configuration.EELFLogger;
24 import com.att.eelf.configuration.EELFManager;
25 import com.google.common.util.concurrent.Futures;
26 import org.apache.commons.lang.StringUtils;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
29 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
30 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
31 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.GenerateSequenceInput;
32 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.GenerateSequenceOutput;
33 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.GenerateSequenceOutputBuilder;
34 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.SequenceGeneratorService;
35 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.dependency.info.dependency.info.Vnfcs;
36 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.inventory.info.inventory.info.vnf.info.Vm;
37 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.response.StatusBuilder;
38 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.response.Transactions;
39 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.response.TransactionsBuilder;
40 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.response.transactions.ActionIdentifier;
41 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.response.transactions.*;
42 import org.opendaylight.yang.gen.v1.org.onap.appc.sequencegenerator.rev170706.response.transactions.responses.ResponseActionBuilder;
43 import org.opendaylight.yangtools.yang.common.RpcResult;
44 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
45 import org.onap.appc.dg.objects.InventoryModel;
46 import org.onap.appc.dg.objects.Node;
47 import org.onap.appc.dg.objects.VnfcDependencyModel;
48 import org.onap.appc.domainmodel.Vnf;
49 import org.onap.appc.domainmodel.Vnfc;
50 import org.onap.appc.domainmodel.Vserver;
51 import org.onap.appc.domainmodel.lcm.VNFOperation;
52 import org.onap.appc.exceptions.APPCException;
53 import org.onap.appc.seqgen.SequenceGenerator;
54 import org.onap.appc.seqgen.impl.SequenceGeneratorFactory;
55 import org.onap.appc.seqgen.objects.Constants;
56 import org.onap.appc.seqgen.objects.PreCheckOption;
57 import org.onap.appc.seqgen.objects.RequestInfo;
58 import org.onap.appc.seqgen.objects.RequestInfoBuilder;
59 import org.onap.appc.seqgen.objects.Response;
60 import org.onap.appc.seqgen.objects.SequenceGeneratorInput;
61 import org.onap.appc.seqgen.objects.SequenceGeneratorInputBuilder;
62 import org.onap.appc.seqgen.objects.Transaction;
63 import java.util.HashMap;
64 import java.util.HashSet;
65 import java.util.LinkedList;
66 import java.util.List;
67 import java.util.Map;
68 import java.util.Set;
69 import java.util.concurrent.ExecutorService;
70 import java.util.concurrent.Executors;
71 import java.util.concurrent.Future;
72
73
74 public class SequenceGeneratorProvider implements AutoCloseable,SequenceGeneratorService{
75     protected DataBroker dataBroker;
76     protected RpcProviderRegistry rpcRegistry;
77     protected NotificationProviderService notificationService;
78     protected BindingAwareBroker.RpcRegistration<SequenceGeneratorService> rpcRegistration;
79     private final EELFLogger log = EELFManager.getInstance().getLogger(SequenceGeneratorProvider.class);
80     private final ExecutorService executor;
81     private final static String APP_NAME = "SequenceGeneratorProvider";
82
83     public SequenceGeneratorProvider(DataBroker dataBroker2, NotificationProviderService notificationProviderService
84             , RpcProviderRegistry rpcRegistry2) {
85         log.info("Creating provider for " + APP_NAME);
86         executor = Executors.newFixedThreadPool(1);
87         this.dataBroker = dataBroker2;
88         this.notificationService = notificationProviderService;
89
90         this.rpcRegistry = rpcRegistry2;
91
92         if (this.rpcRegistry != null) {
93             rpcRegistration = rpcRegistry.addRpcImplementation(SequenceGeneratorService.class, this);
94         }
95         log.info("Initialization complete for " + APP_NAME);
96     }
97
98     @Override
99     public void close() throws Exception {
100         log.info("Closing provider for " + APP_NAME);
101         if(this.executor != null){
102             executor.shutdown();
103         }
104         if(this.rpcRegistration != null){
105             rpcRegistration.close();
106         }
107         log.info("Successfully closed provider for " + APP_NAME);
108     }
109
110     @Override
111     public Future<RpcResult<GenerateSequenceOutput>> generateSequence(GenerateSequenceInput input) {
112         RpcResult<GenerateSequenceOutput> rpcResult=null;
113         log.debug("Received input = " + input );
114         try {
115             if(input.getRequestInfo()==null){
116                 throw new APPCException("Request info is missing in the input");
117             }
118             SequenceGenerator seqGenerator = SequenceGeneratorFactory.getInstance()
119                     .createSequenceGenerator(VNFOperation.findByString(input.getRequestInfo().getAction().name()));
120             SequenceGeneratorInput seqGenInput = buildSeqGenInput(input);
121             List<Transaction> transactions = seqGenerator.generateSequence(seqGenInput);
122             rpcResult = buildSuccessResponse(transactions);
123         } catch (APPCException e) {
124             log.error("Error Generating Sequence",e);
125             rpcResult = buildFailureResponse(e.getMessage());
126         }
127         return Futures.immediateFuture(rpcResult);
128     }
129
130     private RpcResult<GenerateSequenceOutput> buildSuccessResponse(List<Transaction> transactions) {
131         log.info("Building response from the list of transactions");
132         List<Transactions> transactionList = new LinkedList<>();
133         for(Transaction transaction:transactions){
134             ActionIdentifier actionIdentifier = buildActionIdentifierForResponse(transaction);
135             List<PrecheckOptions> precheckOptions = buildPrecheckOptionsForResponse(transaction);
136             List<Responses> responseList = getResponses(transaction);
137             Transactions transactionObj
138                     = new TransactionsBuilder()
139                     .setActionIdentifier(actionIdentifier)
140                     .setAction(transaction.getAction())
141                     .setActionLevel(transaction.getActionLevel())
142                     .setPrecheckOperator(transaction.getPreCheckOperator())
143                     .setPayload(transaction.getPayload())
144                     .setTransactionId(transaction.getTransactionId())
145                     .setPrecheckOptions(precheckOptions)
146                     .setResponses(responseList)
147                     .build();
148             transactionList.add(transactionObj);
149         }
150
151         GenerateSequenceOutputBuilder builder = new GenerateSequenceOutputBuilder()
152                 .setTransactions(transactionList);
153
154         return RpcResultBuilder
155                 .<GenerateSequenceOutput> status(true)
156                 .withResult(builder.build()).build();
157     }
158
159     private ActionIdentifier buildActionIdentifierForResponse(Transaction transaction) {
160         log.info("Adding action identifiers to response.");
161         ActionIdentifier actionIdentifier = null;
162         if(transaction.getActionIdentifier() != null){
163             actionIdentifier = new ActionIdentifierBuilder()
164                     .setVnfId(transaction.getActionIdentifier().getVnfId())
165                     .setVnfcName(transaction.getActionIdentifier().getVnfcName())
166                     .setVserverId(transaction.getActionIdentifier().getvServerId())
167                     .build();
168         }
169         return actionIdentifier;
170     }
171
172     private List<PrecheckOptions> buildPrecheckOptionsForResponse(Transaction transaction) {
173         log.info("Adding Precheck options to response");
174         List<PrecheckOptions> precheckOptions = new LinkedList<>();
175         if(transaction.getPrecheckOptions()!=null){
176             for(PreCheckOption option:transaction.getPrecheckOptions()){
177                 PrecheckOptions precheckOption = new PrecheckOptionsBuilder()
178                         .setParamName(option.getParamName())
179                         .setParamValue(option.getParamValue())
180                         .setPreTransactionId(option.getPreTransactionId())
181                         .setRule(option.getRule())
182                         .build();
183                 precheckOptions.add(precheckOption);
184             }
185         }
186         return precheckOptions;
187     }
188     private List<Responses> getResponses(Transaction transaction) {
189         List<Responses> responseList = new LinkedList<>();
190         for(Response resp : transaction.getResponses()){
191             Map<String,String> responseActions = resp.getResponseAction();
192             ResponseActionBuilder responseActionBuilder = new ResponseActionBuilder();
193             if(responseActions.get(Constants.ResponseAction.WAIT.getAction())!=null){
194                 responseActionBuilder = responseActionBuilder.setWait(Integer.parseInt(responseActions.get(Constants.ResponseAction.WAIT.getAction())));
195             }
196             if(responseActions.get(Constants.ResponseAction.RETRY.getAction())!=null){
197                 responseActionBuilder = responseActionBuilder.setRetry(Integer.parseInt(responseActions.get(Constants.ResponseAction.RETRY.getAction())));
198             }
199             if(responseActions.get(Constants.ResponseAction.CONTINUE.getAction().toLowerCase())!=null){
200                 responseActionBuilder = responseActionBuilder
201                         .setContinue(Boolean.parseBoolean(responseActions.get(Constants.ResponseAction.CONTINUE.getAction().toLowerCase())));
202             }
203             if(responseActions.get(Constants.ResponseAction.IGNORE.getAction()) !=null){
204                 responseActionBuilder = responseActionBuilder.setIgnore(Boolean.parseBoolean(responseActions.get(Constants.ResponseAction.IGNORE.getAction())));
205             }
206             if(responseActions.get(Constants.ResponseAction.STOP.getAction()) !=null){
207                 responseActionBuilder = responseActionBuilder.setStop(Boolean.parseBoolean(responseActions.get(Constants.ResponseAction.STOP.getAction())));
208             }
209             if(responseActions.get(Constants.ResponseAction.JUMP.getAction()) !=null){
210                 responseActionBuilder = responseActionBuilder.setJump(Integer.parseInt(responseActions.get(Constants.ResponseAction.JUMP.getAction())));
211             }
212             Responses response = new ResponsesBuilder()
213                     .setResponseMessage(resp.getResponseMessage())
214                     .setResponseAction(responseActionBuilder.build())
215                     .build();
216             responseList.add(response);
217         }
218         return responseList;
219     }
220
221     private SequenceGeneratorInput buildSeqGenInput(GenerateSequenceInput input) throws APPCException {
222
223         log.info("Building SequenceGeneratorInput from Yang object GenerateSequenceInput.");
224         validateMandatory(input);
225
226         RequestInfo requestInfo = buildRequestInfoForSeqGenInput(input);
227         InventoryModel inventoryModel = readInventoryModel(input);
228
229         VnfcDependencyModel dependencyModel = readDependencyModel(input);
230         if(dependencyModel!=null){
231             validateInventoryModelWithDependencyModel(dependencyModel,inventoryModel);
232         }
233
234         SequenceGeneratorInputBuilder builder = new SequenceGeneratorInputBuilder()
235                 .requestInfo(requestInfo)
236                 .inventoryModel(inventoryModel)
237                 .dependendcyModel(dependencyModel);
238
239         builder = buildCapabilitiesForSeqGenInput(input, builder);
240
241         builder = buildTunableParamsForSeqGenInput(input, builder);
242
243         return builder.build();
244     }
245
246     private SequenceGeneratorInputBuilder buildTunableParamsForSeqGenInput(GenerateSequenceInput input, SequenceGeneratorInputBuilder builder) {
247         log.info("Initializing Tunable Parameters based on YANG object.");
248         if(input.getTunableParameters() != null){
249             builder = builder.tunableParameter(Constants.RETRY_COUNT,String.valueOf(input.getTunableParameters().getRetryCount()))
250                     .tunableParameter(Constants.WAIT_TIME,String.valueOf(input.getTunableParameters().getWaitTime()));
251             if(input.getTunableParameters().getStrategy() !=null){
252                 builder  = builder.tunableParameter(Constants.STRATEGY,input.getTunableParameters().getStrategy().name());
253             }
254         }
255         return builder;
256     }
257
258     private SequenceGeneratorInputBuilder buildCapabilitiesForSeqGenInput(GenerateSequenceInput input, SequenceGeneratorInputBuilder builder) {
259         log.info("Initializing capabilities based on YANG object.");
260         if(input.getCapabilities() !=null){
261             if(input.getCapabilities().getVnf()!=null){
262                 builder = builder.capability("vnf",input.getCapabilities().getVnf());
263             }
264             if(input.getCapabilities().getVnfc()!=null){
265                 builder = builder.capability("vnfc",input.getCapabilities().getVnfc());
266             }
267             if(input.getCapabilities().getVm()!=null){
268                 builder = builder.capability("vm",input.getCapabilities().getVm());
269             }
270             if(input.getCapabilities().getVfModule()!=null){
271                 builder = builder.capability("vf-module",input.getCapabilities().getVfModule());
272             }
273         }
274
275         return builder;
276     }
277
278     private void validateInventoryModelWithDependencyModel(VnfcDependencyModel dependencyModel, InventoryModel inventoryModel) throws APPCException {
279         Set<String> dependencyModelVnfcSet = new HashSet<>();
280         Set<String> dependencyModelMandatoryVnfcSet = new HashSet<>();
281         Set<String> inventoryModelVnfcsSet = new HashSet<>();
282
283         for (Node<Vnfc> node : dependencyModel.getDependencies()) {
284             dependencyModelVnfcSet.add(node.getChild().getVnfcType().toLowerCase());
285             if (node.getChild().isMandatory()) {
286                 dependencyModelMandatoryVnfcSet.add(node.getChild().getVnfcType().toLowerCase());
287             }
288         }
289
290         for (Vnfc vnfc : inventoryModel.getVnf().getVnfcs()) {
291             inventoryModelVnfcsSet.add(vnfc.getVnfcType().toLowerCase());
292         }
293
294         // if dependency model and inventory model contains same set of VNFCs, validation succeed and hence return
295         if (dependencyModelVnfcSet.equals(inventoryModelVnfcsSet)) {
296             return;
297         }
298
299         if (inventoryModelVnfcsSet.size() >= dependencyModelVnfcSet.size()) {
300             Set<String> difference = new HashSet<>(inventoryModelVnfcsSet);
301             difference.removeAll(dependencyModelVnfcSet);
302             log.error("Dependency model is missing following vnfc type(s): " + difference);
303             throw new APPCException("Dependency model is missing following vnfc type(s): " + difference);
304         } else {
305             Set<String> difference = new HashSet<>(dependencyModelMandatoryVnfcSet);
306             difference.removeAll(inventoryModelVnfcsSet);
307             if (difference.size() > 0) {
308                 log.error("Inventory model is missing following mandatory vnfc type(s): " + difference);
309                 throw new APPCException("VMs missing for the mandatory VNFC : " + difference);
310             }
311         }
312     }
313
314     private RequestInfo buildRequestInfoForSeqGenInput(GenerateSequenceInput input) {
315         log.info("Building RequestInfo from Yang object");
316         RequestInfoBuilder requestInfobuilder = buildRequestInformation(input);
317
318         if(input.getRequestInfo().getActionIdentifier() !=null){
319             requestInfobuilder = buildActionIdentifiers(input, requestInfobuilder);
320         }
321
322         return requestInfobuilder.build();
323     }
324
325     private RequestInfoBuilder buildActionIdentifiers(GenerateSequenceInput input, RequestInfoBuilder requestInfobuilder) {
326         log.info("Initializing actionIdentifier for RequestInfo");
327         requestInfobuilder = requestInfobuilder
328                 .actionIdentifier()
329                 .vnfId(input.getRequestInfo().getActionIdentifier().getVnfId())
330                 .vnfcName(input.getRequestInfo().getActionIdentifier().getVnfcName())
331                 .vServerId(input.getRequestInfo().getActionIdentifier().getVserverId());
332         return requestInfobuilder;
333     }
334
335     private RequestInfoBuilder buildRequestInformation(GenerateSequenceInput input) {
336         log.info("Initializing action, actionLevel and payload for RequestInfo");
337         return new RequestInfoBuilder()
338                 .action(input.getRequestInfo().getAction().name())
339                 .actionLevel(input.getRequestInfo().getActionLevel().getName().toLowerCase())
340                 .payload(input.getRequestInfo().getPayload());
341     }
342
343     private void validateMandatory(GenerateSequenceInput input) throws APPCException {
344         if(input.getRequestInfo() ==null){
345             throw new APPCException("Request Info is not present in the request");
346         }
347         if(input.getRequestInfo().getAction() ==null){
348             throw new APPCException("Action is not present in the request");
349         }
350         if(input.getInventoryInfo() ==null){
351             throw new APPCException("inventoryInfo is not provided in the input");
352         }
353         if (input.getInventoryInfo().getVnfInfo()== null) {
354             log.error("vnfInfo is null in the input");
355             throw new APPCException("vnfInfo is missing in the input");
356         }
357         if(input.getInventoryInfo().getVnfInfo().getVm().isEmpty()){
358             log.error("Null vm information in input.");
359             throw new APPCException("VnfInfo is missing in the input");
360         }
361         log.info("Mandatory information present in the request.");
362     }
363
364     private VnfcDependencyModel readDependencyModel(GenerateSequenceInput input) throws APPCException{
365         log.info("Initializing DependencyModel from YANG model.");
366         if(input.getDependencyInfo() == null || input.getDependencyInfo().getVnfcs() ==null || input.getDependencyInfo().getVnfcs().isEmpty()){
367             log.info("No dependency model information is present for the request.");
368             return null;
369         }
370         List<Vnfcs> vnfcs = input.getDependencyInfo().getVnfcs();
371         Set<Node<org.onap.appc.domainmodel.Vnfc>> dependencies = new HashSet<>();
372         Set<String> parentVnfcs=new HashSet<>();
373         Set<String> allVnfcTypes=new HashSet<>();
374         for(Vnfcs vnfcObj:vnfcs){
375             org.onap.appc.domainmodel.Vnfc vnfc = new org.onap.appc.domainmodel.Vnfc();
376             vnfc.setVnfcType(vnfcObj.getVnfcType());
377             allVnfcTypes.add(vnfcObj.getVnfcType());
378             vnfc.setResilienceType(vnfcObj.getResilience());
379             Node<Vnfc> currentNode = buildVnfcNodeForDependenyInfo(dependencies, vnfcObj, vnfc);
380             for(String parentVnfcType:vnfcObj.getParents()){
381                 parentVnfcs.add(parentVnfcType);
382                 Node<Vnfc> parentNode = readNode(parentVnfcType,dependencies);
383                 if(parentNode == null){
384                     Vnfc parentVnfc = new Vnfc();
385                     parentVnfc.setVnfcType(parentVnfcType);
386                     parentNode = new Node<>(parentVnfc);
387                     currentNode.addParent(parentVnfc);
388                     dependencies.add(parentNode);
389                 }
390                 else{
391                     currentNode.addParent(parentNode.getChild());
392                 }
393             }
394         }
395         for(String parent:parentVnfcs){
396             if(!allVnfcTypes.contains(parent)){
397                 throw new APPCException("Dependency model missing vnfc type "+parent);
398             }
399         }
400         return new VnfcDependencyModel(dependencies);
401     }
402
403     private Node<Vnfc> buildVnfcNodeForDependenyInfo(Set<Node<Vnfc>> dependencies, Vnfcs vnfcObj, Vnfc vnfc) {
404         Node<Vnfc> currentNode = readNode(vnfcObj.getVnfcType(),dependencies);
405         if(currentNode == null){
406             currentNode = new Node<>(vnfc);
407             dependencies.add(currentNode);
408         }
409         else{
410             currentNode.getChild().setResilienceType(vnfcObj.getResilience());
411             currentNode.getChild().setMandatory(vnfcObj.isMandatory());
412         }
413         return currentNode;
414     }
415
416     private Node<org.onap.appc.domainmodel.Vnfc> readNode(String vnfcType, Set<Node<org.onap.appc.domainmodel.Vnfc>> dependencies) {
417         for(Node<org.onap.appc.domainmodel.Vnfc> node : dependencies){
418             if(node.getChild().getVnfcType().equalsIgnoreCase(vnfcType)){
419                 return node;
420             }
421         }
422         return null;
423     }
424
425     private InventoryModel readInventoryModel(GenerateSequenceInput input) throws APPCException {
426
427         log.info("Initializing InventoryModel from Yang input model");
428         Vnf vnf = createVnfForInventoryModel(input);
429         Map<org.onap.appc.domainmodel.Vnfc,List<Vserver>> map = new HashMap<>();
430         buildVserverDetailsForInventoryModel(input, vnf, map);
431         for(Map.Entry<org.onap.appc.domainmodel.Vnfc,List<Vserver>> entry:map.entrySet()){
432             org.onap.appc.domainmodel.Vnfc vnfc = entry.getKey();
433             List<Vserver> vmList = entry.getValue();
434             vnfc.addVservers(vmList);
435         }
436         return new InventoryModel(vnf);
437     }
438
439     private void buildVserverDetailsForInventoryModel(GenerateSequenceInput input, Vnf vnf, Map<Vnfc, List<Vserver>> map) throws APPCException {
440         if(input.getInventoryInfo().getVnfInfo().getVm().size()<1){
441             throw  new APPCException("vnfInfo is missing  in the input");
442         }
443         for(Vm vm:input.getInventoryInfo().getVnfInfo().getVm()){
444             if(StringUtils.isBlank(vm.getVserverId())){
445                 throw new APPCException("vserver-id not found ");
446             }
447             Vserver vserver=new Vserver();
448             vserver.setId(vm.getVserverId());
449             if(!StringUtils.isBlank(vm.getVnfc().getVnfcName()) &&
450                 !StringUtils.isBlank(vm.getVnfc().getVnfcType())){
451                 Vnfc vfc = new Vnfc();
452                 vfc.setVnfcName(vm.getVnfc().getVnfcName());
453                 vfc.setVnfcType(vm.getVnfc().getVnfcType());
454                 vserver.setVnfc(vfc);
455                 List<Vserver> vms = map.get(vfc);
456                 if(vms ==null){
457                     vms = new LinkedList<>();
458                     map.put(vfc,vms);
459                 }
460                 vms.add(vserver);
461             }
462             vnf.addVserver(vserver);
463          }
464     }
465
466     private Vnf createVnfForInventoryModel(GenerateSequenceInput input) {
467         log.info("Setting VnfId and VnfType values for Vnf Inventory Model ");
468         Vnf vnf=new Vnf();
469         vnf.setVnfId(input.getInventoryInfo().getVnfInfo().getVnfId());
470         vnf.setVnfType(input.getInventoryInfo().getVnfInfo().getVnfType());
471         return vnf;
472     }
473
474     private RpcResult<GenerateSequenceOutput> buildFailureResponse(String errorMessage){
475         GenerateSequenceOutputBuilder sequenceGeneratorOutputBuilder=new GenerateSequenceOutputBuilder();
476         StatusBuilder statusBuilder =new StatusBuilder();
477         statusBuilder.setCode(401);
478         statusBuilder.setMessage(errorMessage);
479         sequenceGeneratorOutputBuilder.setStatus(statusBuilder.build());
480         return RpcResultBuilder
481                 .<GenerateSequenceOutput> status(true)
482                 .withResult(sequenceGeneratorOutputBuilder.build())
483                 .build();
484     }
485 }