Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • tfs/controller
1 result
Show changes
Commits on Source (14)
Showing
with 8785 additions and 967 deletions
......@@ -171,5 +171,8 @@ local_k8s_deployment.sh
# asdf configuration
.tool-versions
# libyang build files
libyang/
# Other logs
**/logs/*.log.*
......@@ -32,8 +32,11 @@ sudo apt-get --yes --quiet --quiet update
sudo apt-get --yes --quiet --quiet install build-essential cmake libpcre2-dev python3-dev python3-cffi
mkdir libyang
git clone https://github.com/CESNET/libyang.git libyang
git fetch
git checkout v2.1.148
mkdir libyang/build
cd libyang/build
echo "*" > .gitignore
cmake -D CMAKE_BUILD_TYPE:String="Release" ..
make
sudo make install
......
......@@ -61,6 +61,9 @@ RUN apt-get --yes --quiet --quiet update && \
rm -rf /var/lib/apt/lists/*
RUN mkdir -p /var/libyang
RUN git clone https://github.com/CESNET/libyang.git /var/libyang
WORKDIR /var/libyang
RUN git fetch
RUN git checkout v2.1.148
RUN mkdir -p /var/libyang/build
WORKDIR /var/libyang/build
RUN cmake -D CMAKE_BUILD_TYPE:String="Release" ..
......
......@@ -18,6 +18,9 @@ sudo apt-get install python3-dev gcc python3-cffi
```bash
mkdir ~/tfs-ctrl/libyang
git clone https://github.com/CESNET/libyang.git ~/tfs-ctrl/libyang
cd ~/tfs-ctrl/libyang
git fetch
git checkout v2.1.148
mkdir ~/tfs-ctrl/libyang/build
cd ~/tfs-ctrl/libyang/build
cmake -D CMAKE_BUILD_TYPE:String="Release" ..
......
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* Licensed 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.etsi.tfs.policy.policy;
import static org.etsi.tfs.policy.common.ApplicationProperties.INVALID_MESSAGE;
import static org.etsi.tfs.policy.common.ApplicationProperties.VALIDATED_POLICYRULE_STATE;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.groups.UniJoin;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.util.List;
import org.etsi.tfs.policy.context.ContextService;
import org.etsi.tfs.policy.exception.ExternalServiceFailureException;
import org.etsi.tfs.policy.policy.model.PolicyRule;
import org.etsi.tfs.policy.policy.model.PolicyRuleBasic;
import org.etsi.tfs.policy.policy.model.PolicyRuleDevice;
import org.etsi.tfs.policy.policy.model.PolicyRuleState;
import org.etsi.tfs.policy.policy.model.PolicyRuleStateEnum;
import org.etsi.tfs.policy.policy.model.PolicyRuleTypeDevice;
import org.etsi.tfs.policy.policy.service.PolicyRuleConditionValidator;
@ApplicationScoped
public class AddPolicyDeviceImpl {
@Inject private PolicyRuleConditionValidator policyRuleConditionValidator;
@Inject private CommonPolicyServiceImpl commonPolicyServiceImpl;
@Inject private CommonAlarmService commonAlarmService;
@Inject private ContextService contextService;
public Uni<List<Boolean>> returnInvalidDeviceIds(List<String> deviceIds) {
UniJoin.Builder<Boolean> builder = Uni.join().builder();
for (String deviceId : deviceIds) {
final var validatedDeviceId = policyRuleConditionValidator.isDeviceIdValid(deviceId);
builder.add(validatedDeviceId);
}
return builder.joinAll().andFailFast();
}
public Uni<PolicyRuleState> areDeviceOnContext(
List<Boolean> areDevices,
PolicyRuleDevice policyRuleDevice,
PolicyRuleBasic policyRuleBasic) {
if (areDevices.contains(false)) {
var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED,
String.format(
INVALID_MESSAGE, policyRuleDevice.getPolicyRuleBasic().getPolicyRuleId()));
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleTypeDevice = new PolicyRuleTypeDevice(policyRuleDevice);
final var policyRule = new PolicyRule(policyRuleTypeDevice);
final var alarmDescriptorList = commonPolicyServiceImpl.createAlarmDescriptorList(policyRule);
if (alarmDescriptorList.isEmpty()) {
var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED,
String.format(
"Invalid PolicyRuleConditions in PolicyRule with ID: %s",
policyRuleBasic.getPolicyRuleId()));
return Uni.createFrom().item(policyRuleState);
}
return contextService
.setPolicyRule(policyRule)
.onFailure()
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transform(
policyId -> {
commonAlarmService.startMonitoringBasedOnAlarmDescriptors(
policyId, policyRuleDevice, alarmDescriptorList);
return VALIDATED_POLICYRULE_STATE;
});
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* Licensed 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.etsi.tfs.policy.policy;
import static org.etsi.tfs.policy.common.ApplicationProperties.INVALID_MESSAGE;
import static org.etsi.tfs.policy.common.ApplicationProperties.VALIDATED_POLICYRULE_STATE;
import io.smallrye.mutiny.Uni;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.util.List;
import org.etsi.tfs.policy.context.ContextService;
import org.etsi.tfs.policy.context.model.ServiceId;
import org.etsi.tfs.policy.exception.ExternalServiceFailureException;
import org.etsi.tfs.policy.monitoring.model.AlarmDescriptor;
import org.etsi.tfs.policy.policy.model.PolicyRule;
import org.etsi.tfs.policy.policy.model.PolicyRuleBasic;
import org.etsi.tfs.policy.policy.model.PolicyRuleService;
import org.etsi.tfs.policy.policy.model.PolicyRuleState;
import org.etsi.tfs.policy.policy.model.PolicyRuleStateEnum;
import org.etsi.tfs.policy.policy.model.PolicyRuleTypeService;
@ApplicationScoped
public class AddPolicyServiceImpl {
@Inject private CommonPolicyServiceImpl commonPolicyService;
@Inject private CommonAlarmService commonAlarmService;
@Inject private ContextService contextService;
public Uni<PolicyRuleState> constructPolicyStateBasedOnCriteria(
Boolean isService,
ServiceId serviceId,
PolicyRuleService policyRuleService,
PolicyRuleBasic policyRuleBasic) {
if (!isService) {
var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED, String.format(INVALID_MESSAGE, serviceId));
return Uni.createFrom().item(policyRuleState);
}
final var policyRuleTypeService = new PolicyRuleTypeService(policyRuleService);
final var policyRule = new PolicyRule(policyRuleTypeService);
final var alarmDescriptorList = commonPolicyService.createAlarmDescriptorList(policyRule);
if (alarmDescriptorList.isEmpty()) {
var policyRuleState =
new PolicyRuleState(
PolicyRuleStateEnum.POLICY_FAILED,
String.format(
"Invalid PolicyRuleConditions in PolicyRule with ID: %s",
policyRuleBasic.getPolicyRuleId()));
return Uni.createFrom().item(policyRuleState);
}
return setPolicyRuleOnContextAndReturnState(policyRule, policyRuleService, alarmDescriptorList);
}
private Uni<PolicyRuleState> setPolicyRuleOnContextAndReturnState(
PolicyRule policyRule,
PolicyRuleService policyRuleService,
List<AlarmDescriptor> alarmDescriptorList) {
return contextService
.setPolicyRule(policyRule)
.onFailure()
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transform(
policyId -> {
commonAlarmService.startMonitoringBasedOnAlarmDescriptors(
policyId, policyRuleService, alarmDescriptorList);
return VALIDATED_POLICYRULE_STATE;
});
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* Licensed 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.etsi.tfs.policy.policy;
import static org.etsi.tfs.policy.common.ApplicationProperties.PROVISIONED_POLICYRULE_STATE;
import static org.etsi.tfs.policy.common.ApplicationProperties.VALIDATED_POLICYRULE_STATE;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.subscription.Cancellable;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import org.etsi.tfs.policy.monitoring.MonitoringService;
import org.etsi.tfs.policy.monitoring.model.AlarmDescriptor;
import org.etsi.tfs.policy.monitoring.model.AlarmResponse;
import org.etsi.tfs.policy.monitoring.model.AlarmSubscription;
import org.etsi.tfs.policy.policy.model.PolicyRuleDevice;
import org.etsi.tfs.policy.policy.model.PolicyRuleService;
import org.jboss.logging.Logger;
@ApplicationScoped
public class CommonAlarmService {
private static final Logger LOGGER = Logger.getLogger(CommonAlarmService.class);
@Inject private CommonPolicyServiceImpl commonPolicyServiceImpl;
@Inject private MonitoringService monitoringService;
public void startMonitoringBasedOnAlarmDescriptors(
String policyId,
PolicyRuleDevice policyRuleDevice,
List<AlarmDescriptor> alarmDescriptorList) {
commonPolicyServiceImpl.setPolicyRuleDeviceToContext(
policyRuleDevice, VALIDATED_POLICYRULE_STATE);
commonPolicyServiceImpl.noAlarms = 0;
List<Uni<String>> alarmIds = createAlarmList(alarmDescriptorList);
List<Multi<AlarmResponse>> alarmResponseStreamList =
transformAlarmIds(alarmIds, policyRuleDevice);
// Merge the promised alarms into one stream (Multi Object)
final var multi = Multi.createBy().merging().streams(alarmResponseStreamList);
commonPolicyServiceImpl.setPolicyRuleDeviceToContext(
policyRuleDevice, PROVISIONED_POLICYRULE_STATE);
commonPolicyServiceImpl
.getSubscriptionList()
.put(policyId, monitorAlarmResponseForDevice(multi));
// TODO: Resubscribe to the stream, if it has ended
// TODO: Redesign evaluation of action
// evaluateAction(policyRule, alarmDescriptorList, multi);
}
public void startMonitoringBasedOnAlarmDescriptors(
String policyId,
PolicyRuleService policyRuleService,
List<AlarmDescriptor> alarmDescriptorList) {
commonPolicyServiceImpl.setPolicyRuleServiceToContext(
policyRuleService, VALIDATED_POLICYRULE_STATE);
commonPolicyServiceImpl.noAlarms = 0;
List<Uni<String>> alarmIds =
createAlarmList(alarmDescriptorList); // setAllarmtomonitoring get back alarmid
List<Multi<AlarmResponse>> alarmResponseStreamList =
transformAlarmIds(alarmIds, policyRuleService);
// Merge the promised alarms into one stream (Multi Object)
final var multi = Multi.createBy().merging().streams(alarmResponseStreamList);
commonPolicyServiceImpl.setPolicyRuleServiceToContext(
policyRuleService, PROVISIONED_POLICYRULE_STATE);
commonPolicyServiceImpl
.getSubscriptionList()
.put(policyId, monitorAlarmResponseForService(multi));
// TODO: Resubscribe to the stream, if it has ended
// TODO: Redesign evaluation of action
// evaluateAction(policyRule, alarmDescriptorList, multi);
}
/**
* Transform the alarmIds into promised alarms returned from the getAlarmResponseStream
*
* @param alarmIds the list of alarm ids
* @param policyRuleService the policy rule service
* @return
*/
private List<Multi<AlarmResponse>> transformAlarmIds(
List<Uni<String>> alarmIds, PolicyRuleService policyRuleService) {
List<Multi<AlarmResponse>> alarmResponseStreamList = new ArrayList<>();
for (Uni<String> alarmId : alarmIds) {
Multi<AlarmResponse> alarmResponseStream =
alarmId.onItem().transformToMulti(id -> setPolicyMonitor(policyRuleService, id));
alarmResponseStreamList.add(alarmResponseStream);
}
return alarmResponseStreamList;
}
private List<Multi<AlarmResponse>> transformAlarmIds(
List<Uni<String>> alarmIds, PolicyRuleDevice policyRuleDevice) {
// Transform the alarmIds into promised alarms returned from the
// getAlarmResponseStream
List<Multi<AlarmResponse>> alarmResponseStreamList = new ArrayList<>();
for (Uni<String> alarmId : alarmIds) {
alarmResponseStreamList.add(
alarmId.onItem().transformToMulti(id -> setPolicyMonitor(policyRuleDevice, id)));
}
return alarmResponseStreamList;
}
private Multi<AlarmResponse> setPolicyMonitor(PolicyRuleService policyRuleService, String id) {
commonPolicyServiceImpl.getAlarmPolicyRuleServiceMap().put(id, policyRuleService);
// TODO: Create infinite subscription
var alarmSubscription = new AlarmSubscription(id, 259200, 5000);
return monitoringService.getAlarmResponseStream(alarmSubscription);
}
private Multi<AlarmResponse> setPolicyMonitor(PolicyRuleDevice policyRuleDevice, String id) {
commonPolicyServiceImpl.getAlarmPolicyRuleDeviceMap().put(id, policyRuleDevice);
// TODO: Create infinite subscription
var alarmSubscription = new AlarmSubscription(id, 259200, 5000);
return monitoringService.getAlarmResponseStream(alarmSubscription);
}
/**
* Create an alarmIds list that contains the promised ids returned from setKpiAlarm
*
* @param alarmDescriptorList the list of alarm descriptors
* @return the list of alarm descriptors
*/
public List<Uni<String>> createAlarmList(List<AlarmDescriptor> alarmDescriptorList) {
List<Uni<String>> alarmIds = new ArrayList<Uni<String>>();
for (AlarmDescriptor alarmDescriptor : alarmDescriptorList) {
LOGGER.infof("alarmDescriptor:");
LOGGER.infof(alarmDescriptor.toString());
alarmIds.add(monitoringService.setKpiAlarm(alarmDescriptor));
}
return alarmIds;
}
private Cancellable monitorAlarmResponseForService(Multi<AlarmResponse> multi) {
return multi
.subscribe()
.with(
alarmResponse -> {
LOGGER.infof("**************************Received Alarm!**************************");
LOGGER.infof("alarmResponse:");
LOGGER.info(alarmResponse);
LOGGER.info(alarmResponse.getAlarmId());
commonPolicyServiceImpl.applyActionService(alarmResponse.getAlarmId());
});
}
private Cancellable monitorAlarmResponseForDevice(Multi<AlarmResponse> multi) {
return multi
.subscribe()
.with(
alarmResponse -> {
LOGGER.infof("**************************Received Alarm!**************************");
LOGGER.infof("alarmResponse:");
LOGGER.info(alarmResponse);
LOGGER.info(alarmResponse.getAlarmId());
commonPolicyServiceImpl.applyActionDevice(alarmResponse.getAlarmId());
});
}
}
......@@ -89,6 +89,23 @@ public interface ContextService extends MutinyService {
io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeConnection(context.ContextOuterClass.ConnectionId request);
/**
* <pre>
* ------------------------------ Experimental -----------------------------
* </pre>
*/
io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfigList> getOpticalConfig(context.ContextOuterClass.Empty request);
io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfigId> setOpticalConfig(context.ContextOuterClass.OpticalConfig request);
io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfig> selectOpticalConfig(context.ContextOuterClass.OpticalConfigId request);
io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> setOpticalLink(context.ContextOuterClass.OpticalLink request);
io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalLink> getOpticalLink(context.ContextOuterClass.OpticalLinkId request);
io.smallrye.mutiny.Uni<context.ContextOuterClass.Fiber> getFiber(context.ContextOuterClass.FiberId request);
io.smallrye.mutiny.Multi<context.ContextOuterClass.ContextEvent> getContextEvents(context.ContextOuterClass.Empty request);
io.smallrye.mutiny.Multi<context.ContextOuterClass.TopologyEvent> getTopologyEvents(context.ContextOuterClass.Empty request);
......
......@@ -391,6 +391,60 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
}
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfigList> getOpticalConfig(context.ContextOuterClass.Empty request) {
try {
return delegate.getOpticalConfig(request);
} catch (UnsupportedOperationException e) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfigId> setOpticalConfig(context.ContextOuterClass.OpticalConfig request) {
try {
return delegate.setOpticalConfig(request);
} catch (UnsupportedOperationException e) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfig> selectOpticalConfig(context.ContextOuterClass.OpticalConfigId request) {
try {
return delegate.selectOpticalConfig(request);
} catch (UnsupportedOperationException e) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> setOpticalLink(context.ContextOuterClass.OpticalLink request) {
try {
return delegate.setOpticalLink(request);
} catch (UnsupportedOperationException e) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalLink> getOpticalLink(context.ContextOuterClass.OpticalLinkId request) {
try {
return delegate.getOpticalLink(request);
} catch (UnsupportedOperationException e) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.Fiber> getFiber(context.ContextOuterClass.FiberId request) {
try {
return delegate.getFiber(request);
} catch (UnsupportedOperationException e) {
throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
}
}
@Override
public io.smallrye.mutiny.Multi<context.ContextOuterClass.ContextEvent> getContextEvents(context.ContextOuterClass.Empty request) {
try {
......
......@@ -235,6 +235,36 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
return stub.removeConnection(request);
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfigList> getOpticalConfig(context.ContextOuterClass.Empty request) {
return stub.getOpticalConfig(request);
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfigId> setOpticalConfig(context.ContextOuterClass.OpticalConfig request) {
return stub.setOpticalConfig(request);
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalConfig> selectOpticalConfig(context.ContextOuterClass.OpticalConfigId request) {
return stub.selectOpticalConfig(request);
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> setOpticalLink(context.ContextOuterClass.OpticalLink request) {
return stub.setOpticalLink(request);
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.OpticalLink> getOpticalLink(context.ContextOuterClass.OpticalLinkId request) {
return stub.getOpticalLink(request);
}
@Override
public io.smallrye.mutiny.Uni<context.ContextOuterClass.Fiber> getFiber(context.ContextOuterClass.FiberId request) {
return stub.getFiber(request);
}
@Override
public io.smallrye.mutiny.Multi<context.ContextOuterClass.ContextEvent> getContextEvents(context.ContextOuterClass.Empty request) {
return stub.getContextEvents(request);
......
......@@ -3,8 +3,8 @@ apiVersion: v1
kind: Service
metadata:
annotations:
app.quarkus.io/commit-id: aa8541cd42120ff91ef0573b05beb1e1d0861617
app.quarkus.io/build-timestamp: 2024-02-15 - 09:57:46 +0000
app.quarkus.io/commit-id: 182b55a46135040b71a5980de9f72d94a85db2e8
app.quarkus.io/build-timestamp: 2024-04-08 - 08:15:43 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /q/metrics
prometheus.io/port: "8080"
......@@ -21,14 +21,14 @@ spec:
port: 443
protocol: TCP
targetPort: 8443
- name: http
port: 9192
protocol: TCP
targetPort: 8080
- name: grpc
port: 6060
protocol: TCP
targetPort: 6060
- name: http
port: 9192
protocol: TCP
targetPort: 8080
selector:
app.kubernetes.io/name: policyservice
type: ClusterIP
......@@ -37,8 +37,8 @@ apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
app.quarkus.io/commit-id: aa8541cd42120ff91ef0573b05beb1e1d0861617
app.quarkus.io/build-timestamp: 2024-02-15 - 09:57:46 +0000
app.quarkus.io/commit-id: 182b55a46135040b71a5980de9f72d94a85db2e8
app.quarkus.io/build-timestamp: 2024-04-08 - 08:15:43 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /q/metrics
prometheus.io/port: "8080"
......@@ -57,8 +57,8 @@ spec:
template:
metadata:
annotations:
app.quarkus.io/commit-id: aa8541cd42120ff91ef0573b05beb1e1d0861617
app.quarkus.io/build-timestamp: 2024-02-15 - 09:57:46 +0000
app.quarkus.io/commit-id: 182b55a46135040b71a5980de9f72d94a85db2e8
app.quarkus.io/build-timestamp: 2024-04-08 - 08:15:43 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /q/metrics
prometheus.io/port: "8080"
......@@ -75,12 +75,12 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: CONTEXT_SERVICE_HOST
value: contextservice
- name: SERVICE_SERVICE_HOST
value: serviceservice
- name: MONITORING_SERVICE_HOST
value: monitoringservice
- name: CONTEXT_SERVICE_HOST
value: contextservice
image: labs.etsi.org:5050/tfs/controller/policy:0.1.0
imagePullPolicy: Always
livenessProbe:
......@@ -98,12 +98,12 @@ spec:
- containerPort: 8443
name: https
protocol: TCP
- containerPort: 8080
name: http
protocol: TCP
- containerPort: 6060
name: grpc
protocol: TCP
- containerPort: 8080
name: http
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
......
......@@ -23,12 +23,12 @@ import org.etsi.tfs.ztp.context.ContextService;
import org.etsi.tfs.ztp.context.model.Device;
import org.etsi.tfs.ztp.context.model.DeviceConfig;
import org.etsi.tfs.ztp.device.DeviceService;
import org.etsi.tfs.ztp.exception.ExternalServiceFailureException;
import org.jboss.logging.Logger;
@ApplicationScoped
public class ZtpServiceImpl implements ZtpService {
private static final Logger LOGGER = Logger.getLogger(ZtpServiceImpl.class);
// private static final String MESSAGE = "Retrieved %s";
private final DeviceService deviceService;
private final ContextService contextService;
......@@ -41,128 +41,104 @@ public class ZtpServiceImpl implements ZtpService {
@Override
public Uni<Device> addDevice(String deviceId) {
final var deserializedDeviceUni = contextService.getDevice(deviceId);
deserializedDeviceUni
return contextService
.getDevice(deviceId)
.onFailure()
.recoverWithNull()
.subscribe()
.with(
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transformToUni(
device -> {
final var id = deviceId;
if (device == null) {
LOGGER.warnf("%s is null. Ignoring...", device);
return;
}
if (device.isEnabled()) {
LOGGER.warnf("%s has already been enabled. Ignoring...", device);
return;
return Uni.createFrom().failure(new Exception("Device is already enabled"));
} else {
return addDeviceTo(device, deviceId);
}
});
}
// LOGGER.infof(MESSAGE, device);
final var initialConfiguration =
deviceService.getInitialConfiguration(device.getDeviceId());
device.enableDevice();
LOGGER.infof("Enabled device [%s]", id);
public Uni<Device> addDeviceTo(Device device, String deviceId) {
LOGGER.infof("Enabling device with ID [%s]", deviceId);
device.enableDevice();
initialConfiguration
.subscribe()
.with(
deviceConfig -> {
device.setDeviceConfiguration(deviceConfig);
final var configuredDeviceIdUni = deviceService.configureDevice(device);
final Uni<DeviceConfig> initialConfiguration = deviceService.getInitialConfiguration(deviceId);
configuredDeviceIdUni
.subscribe()
.with(
configuredDeviceId ->
LOGGER.infof(
"Device [%s] has been successfully enabled and configured with %s.\n",
id, deviceConfig));
return initialConfiguration
.onItem()
.transformToUni(
deviceConfig -> {
device.setDeviceConfiguration(deviceConfig);
LOGGER.infof(
"Configuring device with ID [%s] with initial configuration %s",
deviceId, deviceConfig);
return deviceService
.configureDevice(device)
.map(
configuredDeviceId -> {
LOGGER.infof(
"Device with ID [%s] has been successfully enabled and configured.",
deviceId);
return device;
});
});
return deserializedDeviceUni;
}
@Override
public Uni<Device> deleteDevice(String deviceId) {
final var deserializedDeviceUni = contextService.getDevice(deviceId);
deserializedDeviceUni
return contextService
.getDevice(deviceId)
.onFailure()
.recoverWithNull()
.subscribe()
.with(
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transformToUni(
device -> {
final var id = deviceId;
if (device == null) {
LOGGER.warnf("%s is null. Ignoring...", device);
return;
}
if (device.isDisabled()) {
LOGGER.warnf("%s has already been disabled. Ignoring...", device);
return;
LOGGER.warnf("Device with ID %s has already been disabled. Ignoring...", deviceId);
return Uni.createFrom().nullItem();
} else {
LOGGER.infof("Disabling device with ID [%s]", deviceId);
device.disableDevice();
return deviceService
.deleteDevice(deviceId)
.onItem()
.transform(
emptyMessage -> {
LOGGER.infof(
"Device with ID [%s] has been successfully deleted.", deviceId);
return device;
});
}
device.disableDevice();
LOGGER.infof("Disabled device [%s]", id);
// LOGGER.infof(MESSAGE, device);
final var empty = deviceService.deleteDevice(device.getDeviceId());
empty
.subscribe()
.with(
emptyMessage ->
LOGGER.infof("Device [%s] has been successfully deleted.\n", id));
});
return deserializedDeviceUni;
}
@Override
public Uni<Device> updateDevice(String deviceId, DeviceConfig deviceConfig) {
final var deserializedDeviceUni = contextService.getDevice(deviceId);
deserializedDeviceUni
return contextService
.getDevice(deviceId)
.onFailure()
.recoverWithNull()
.subscribe()
.with(
.transform(failure -> new ExternalServiceFailureException(failure.getMessage()))
.onItem()
.transformToUni(
device -> {
final var id = deviceId;
if (device == null) {
LOGGER.warnf("%s is null. Ignoring...", device);
return;
}
if (!device.isEnabled()) {
LOGGER.warnf("Cannot update disabled device %s. Ignoring...", device);
return;
}
// LOGGER.infof(MESSAGE, device);
device.setDeviceConfiguration(deviceConfig);
final var updatedDeviceIdUni = deviceService.configureDevice(device);
updatedDeviceIdUni
.subscribe()
.with(
configuredDeviceId ->
LOGGER.warnf("Cannot update disabled device %s. Ignoring...", deviceId);
return Uni.createFrom().nullItem();
} else {
LOGGER.infof("Updating configuration of device with ID [%s]", deviceId);
device.setDeviceConfiguration(deviceConfig);
return deviceService
.configureDevice(device)
.onItem()
.transform(
configuredDeviceId -> {
LOGGER.infof(
"Device [%s] has been successfully updated with %s.\n",
id, deviceConfig));
"Device with ID [%s] has been successfully updated with %s.",
deviceId, deviceConfig);
return device;
});
}
});
return deserializedDeviceUni;
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* Licensed 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.etsi.tfs.ztp.exception;
public class ExternalServiceFailureException extends RuntimeException {
public ExternalServiceFailureException(String message, Exception e) {
super(message, e);
}
public ExternalServiceFailureException(String message) {
super(message);
}
}
/*
* Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
*
* Licensed 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.etsi.tfs.ztp.exception;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.quarkus.grpc.ExceptionHandlerProvider;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GeneralExceptionHandler implements ExceptionHandlerProvider {
@Override
public <ReqT, RespT> io.quarkus.grpc.ExceptionHandler<ReqT, RespT> createHandler(
ServerCall.Listener<ReqT> listener, ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
return new HelloExceptionHandler<>(listener, serverCall, metadata);
}
@Override
public Throwable transform(Throwable t) {
if (t instanceof ExternalServiceFailureException) {
return new StatusRuntimeException(Status.INTERNAL.withDescription(t.getMessage()));
} else {
return ExceptionHandlerProvider.toStatusException(t, true);
}
}
private static class HelloExceptionHandler<A, B> extends io.quarkus.grpc.ExceptionHandler<A, B> {
public HelloExceptionHandler(
ServerCall.Listener<A> listener, ServerCall<A, B> call, Metadata metadata) {
super(listener, call, metadata);
}
@Override
protected void handleException(Throwable t, ServerCall<A, B> call, Metadata metadata) {
StatusRuntimeException sre =
(StatusRuntimeException) ExceptionHandlerProvider.toStatusException(t, true);
Metadata trailers = sre.getTrailers() != null ? sre.getTrailers() : metadata;
call.close(sre.getStatus(), trailers);
}
}
}
......@@ -15,6 +15,11 @@
ztp:
should-subscribe-to-context-component: true
quarkus:
package:
type: mutable-jar
live-reload:
password: 1234
url: http://0.0.0.0:8080
banner:
path: teraflow-ztp-banner.txt
grpc:
......