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 (6)
Showing
with 7851 additions and 220 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" ..
......
......@@ -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:
......
......@@ -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: 9fcc34bb0e7806d8a5ca5f75cbf3cb9e3358d756
app.quarkus.io/build-timestamp: 2024-02-15 - 11:02:55 +0000
app.quarkus.io/commit-id: 7fce72764fa6bb9b37b407bbcba502cc0a23735f
app.quarkus.io/build-timestamp: 2024-04-04 - 09:35:22 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /q/metrics
prometheus.io/port: "8080"
......@@ -17,18 +17,18 @@ metadata:
name: ztpservice
spec:
ports:
- name: https
port: 443
- name: http
port: 9192
protocol: TCP
targetPort: 8443
targetPort: 8080
- name: grpc
port: 5050
protocol: TCP
targetPort: 5050
- name: http
port: 9192
- name: https
port: 443
protocol: TCP
targetPort: 8080
targetPort: 8443
selector:
app.kubernetes.io/name: ztpservice
type: ClusterIP
......@@ -37,8 +37,8 @@ apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
app.quarkus.io/commit-id: 9fcc34bb0e7806d8a5ca5f75cbf3cb9e3358d756
app.quarkus.io/build-timestamp: 2024-02-15 - 11:02:55 +0000
app.quarkus.io/commit-id: 7fce72764fa6bb9b37b407bbcba502cc0a23735f
app.quarkus.io/build-timestamp: 2024-04-04 - 09:35:22 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /q/metrics
prometheus.io/port: "8080"
......@@ -46,8 +46,8 @@ metadata:
labels:
app: ztpservice
app.kubernetes.io/managed-by: quarkus
app.kubernetes.io/version: 0.2.0
app.kubernetes.io/name: ztpservice
app.kubernetes.io/version: 0.2.0
name: ztpservice
spec:
replicas: 1
......@@ -57,8 +57,8 @@ spec:
template:
metadata:
annotations:
app.quarkus.io/commit-id: 9fcc34bb0e7806d8a5ca5f75cbf3cb9e3358d756
app.quarkus.io/build-timestamp: 2024-02-15 - 11:02:55 +0000
app.quarkus.io/commit-id: 7fce72764fa6bb9b37b407bbcba502cc0a23735f
app.quarkus.io/build-timestamp: 2024-04-04 - 09:35:22 +0000
prometheus.io/scrape: "true"
prometheus.io/path: /q/metrics
prometheus.io/port: "8080"
......@@ -66,8 +66,8 @@ spec:
labels:
app: ztpservice
app.kubernetes.io/managed-by: quarkus
app.kubernetes.io/version: 0.2.0
app.kubernetes.io/name: ztpservice
app.kubernetes.io/version: 0.2.0
spec:
containers:
- env:
......@@ -75,10 +75,10 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: CONTEXT_SERVICE_HOST
value: contextservice
- name: DEVICE_SERVICE_HOST
value: deviceservice
- name: CONTEXT_SERVICE_HOST
value: contextservice
image: labs.etsi.org:5050/tfs/controller/ztp:0.2.0
imagePullPolicy: Always
livenessProbe:
......@@ -93,14 +93,14 @@ spec:
timeoutSeconds: 10
name: ztpservice
ports:
- containerPort: 8443
name: https
- containerPort: 8080
name: http
protocol: TCP
- containerPort: 5050
name: grpc
protocol: TCP
- containerPort: 8080
name: http
- containerPort: 8443
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
......