All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.example.provider1.OperationHandler Maven / Gradle / Ivy

package com.example.provider1;

import com.example.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.somda.sdc.biceps.common.MdibStateModifications;
import org.somda.sdc.biceps.common.storage.PreprocessingException;
import org.somda.sdc.biceps.model.message.InvocationError;
import org.somda.sdc.biceps.model.message.InvocationState;
import org.somda.sdc.biceps.model.participant.EnumStringMetricDescriptor;
import org.somda.sdc.biceps.model.participant.LocalizedText;
import org.somda.sdc.biceps.model.participant.NumericMetricDescriptor;
import org.somda.sdc.biceps.model.participant.NumericMetricState;
import org.somda.sdc.biceps.model.participant.NumericMetricValue;
import org.somda.sdc.biceps.model.participant.SetStringOperationDescriptor;
import org.somda.sdc.biceps.model.participant.SetValueOperationDescriptor;
import org.somda.sdc.biceps.model.participant.StringMetricState;
import org.somda.sdc.biceps.model.participant.StringMetricValue;
import org.somda.sdc.biceps.provider.access.LocalMdibAccess;
import org.somda.sdc.glue.provider.sco.Context;
import org.somda.sdc.glue.provider.sco.IncomingSetServiceRequest;
import org.somda.sdc.glue.provider.sco.InvocationResponse;
import org.somda.sdc.glue.provider.sco.OperationInvocationReceiver;

import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Optional;

/**
 * This class provides a handler for incoming operations on the sdc provider.
 * 

* It implements generic handlers for some operations, which enables handling operations easily, although * a real application should be a little more specialized in its handling. */ public class OperationHandler implements OperationInvocationReceiver { private static final Logger LOG = LoggerFactory.getLogger(OperationHandler.class); private final LocalMdibAccess mdibAccess; public OperationHandler(LocalMdibAccess mdibAccess) { this.mdibAccess = mdibAccess; } LocalizedText createLocalizedText(String text) { return createLocalizedText(text, "en"); } LocalizedText createLocalizedText(String text, String lang) { var localizedText = new LocalizedText(); localizedText.setValue(text); localizedText.setLang(lang); return localizedText; } InvocationResponse genericSetValue(Context context, BigDecimal data) { // TODO: Check if state is modifiable context.sendSuccessfulReport(InvocationState.START); String operationHandle = context.getOperationHandle(); LOG.debug("Received SetValue request for {}: {}", operationHandle, data); // find operation target var setNumeric = mdibAccess.getDescriptor(operationHandle, SetValueOperationDescriptor.class).orElseThrow(() -> { var errorMessage = createLocalizedText("Operation target cannot be found"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.OTH, List.of(errorMessage)); throw new RuntimeException( String.format("Operation descriptor %s missing", operationHandle) ); } ); String operationTargetHandle = setNumeric.getOperationTarget(); var targetDesc = mdibAccess.getDescriptor(operationTargetHandle, NumericMetricDescriptor.class).orElseThrow(() -> { var errorMessage = createLocalizedText("Operation target cannot be found"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.OTH, List.of(errorMessage)); throw new RuntimeException( String.format("Operation target descriptor %s missing", operationTargetHandle) ); }); // find allowed range for descriptor and verify it's within targetDesc.getTechnicalRange().forEach(range -> { if (range.getLower() != null && range.getLower().compareTo(data) > 0) { // value too small var errorMessage = createLocalizedText("Value too small"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.OTH, List.of(errorMessage)); throw new RuntimeException( String.format("Operation set value below lower limit of %s, was %s", range.getLower(), data) ); } if (range.getUpper() != null && range.getUpper().compareTo(data) < 0) { // value too big var errorMessage = createLocalizedText("Value too big"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.OTH, List.of(errorMessage)); throw new RuntimeException( String.format("Operation set value below lower limit of %s, was %s", range.getLower(), data) ); } } ); var targetState = mdibAccess.getState(operationTargetHandle, NumericMetricState.class).orElseThrow(() -> { var errorMessage = createLocalizedText("Operation target state cannot be found"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.OTH, List.of(errorMessage)); throw new RuntimeException( String.format("Operation target descriptor %s missing", operationTargetHandle) ); }); if (targetState.getMetricValue() == null) { targetState.setMetricValue(new NumericMetricValue()); } targetState.getMetricValue().setValue(data); targetState.getMetricValue().setDeterminationTime(Instant.now()); ProviderUtil.addMetricQualityDemo(targetState.getMetricValue()); final MdibStateModifications mod = MdibStateModifications.create(MdibStateModifications.Type.METRIC); mod.add(targetState); try { mdibAccess.writeStates(mod); context.sendSuccessfulReport(InvocationState.FIN); return context.createSuccessfulResponse(InvocationState.FIN); } catch (PreprocessingException e) { LOG.error("Error while writing states", e); var errorMessage = createLocalizedText("Error while writing states"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.UNSPEC, List.of(errorMessage)); return context.createUnsuccessfulResponse(InvocationState.FAIL, InvocationError.UNSPEC, List.of(errorMessage)); } } InvocationResponse genericSetString(Context context, String data, boolean isEnumString) { // TODO: Check if state is modifiable context.sendSuccessfulReport(InvocationState.START); String operationHandle = context.getOperationHandle(); LOG.debug("Received SetString for {}: {}", operationHandle, data); // find operation target var setString = mdibAccess.getDescriptor(operationHandle, SetStringOperationDescriptor.class).orElseThrow(() -> { var errorMessage = createLocalizedText("Operation target cannot be found"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.OTH, List.of(errorMessage)); throw new RuntimeException( String.format("Operation descriptor %s missing", operationHandle) ); } ); String operationTargetHandle = setString.getOperationTarget(); // verify if new data is allowed for enum strings if (isEnumString) { var targetDesc = mdibAccess.getDescriptor(operationTargetHandle, EnumStringMetricDescriptor.class).orElseThrow(() -> { var errorMessage = createLocalizedText("Operation target descriptor cannot be found"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.OTH, List.of(errorMessage)); throw new RuntimeException( String.format("Operation target descriptor %s missing", operationTargetHandle) ); }); // validate data is allowed Optional first = targetDesc.getAllowedValue().stream().filter(x -> x.getValue().equals(data)).findFirst(); if (first.isEmpty()) { // not allowed value, bye bye var errormessage = createLocalizedText("Value is not allowed here"); return context.createUnsuccessfulResponse(mdibAccess.getMdibVersion(), InvocationState.FAIL, InvocationError.UNSPEC, List.of(errormessage)); } } var targetState = mdibAccess.getState(operationTargetHandle, StringMetricState.class).orElseThrow(() -> { var errorMessage = createLocalizedText("Operation target state cannot be found"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.OTH, List.of(errorMessage)); throw new RuntimeException( String.format("Operation target descriptor %s missing", operationTargetHandle) ); }); if (targetState.getMetricValue() == null) { targetState.setMetricValue(new StringMetricValue()); } targetState.getMetricValue().setValue(data); targetState.getMetricValue().setDeterminationTime(Instant.now()); ProviderUtil.addMetricQualityDemo(targetState.getMetricValue()); final MdibStateModifications mod = MdibStateModifications.create(MdibStateModifications.Type.METRIC); mod.add(targetState); try { mdibAccess.writeStates(mod); context.sendSuccessfulReport(InvocationState.FIN); return context.createSuccessfulResponse(InvocationState.FIN); } catch (PreprocessingException e) { LOG.error("Error while writing states", e); var errorMessage = createLocalizedText("Error while writing states"); context.sendUnsuccessfulReport(InvocationState.FAIL, InvocationError.UNSPEC, List.of(errorMessage)); return context.createUnsuccessfulResponse(InvocationState.FAIL, InvocationError.UNSPEC, List.of(errorMessage)); } } @IncomingSetServiceRequest(operationHandle = Constants.HANDLE_SET_VALUE) InvocationResponse setSettableNumericMetric(Context context, BigDecimal data) { return genericSetValue(context, data); } @IncomingSetServiceRequest(operationHandle = Constants.HANDLE_SET_STRING) InvocationResponse setSettableStringMetric(Context context, String data) { return genericSetString(context, data, false); } @IncomingSetServiceRequest(operationHandle = Constants.HANDLE_SET_STRING_ENUM) InvocationResponse setSettableEnumMetric(Context context, String data) { return genericSetString(context, data, true); } @IncomingSetServiceRequest(operationHandle = Constants.HANDLE_ACTIVATE, listType = String.class) InvocationResponse activateExample(Context context, List args) { context.sendSuccessfulReport(InvocationState.START); LOG.debug("Received Activate for {}", Constants.HANDLE_ACTIVATE); context.sendSuccessfulReport(InvocationState.FIN); return context.createSuccessfulResponse(mdibAccess.getMdibVersion(), InvocationState.FIN); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy