Skip to content

Commit

Permalink
feat: Improve the graph load time by reducing calls to bundleContext (#…
Browse files Browse the repository at this point in the history
…4574)

* feat: Improve the graph load time by reducing calls to bundleContext

Signed-off-by: MMaiero <[email protected]>

* fix: fixed tests

Signed-off-by: MMaiero <[email protected]>

* fix: Removed unused method

Signed-off-by: Nicola Timeus <[email protected]>

* Updated copyright headers

Signed-off-by: Nicola Timeus <[email protected]>

---------

Signed-off-by: MMaiero <[email protected]>
Signed-off-by: Nicola Timeus <[email protected]>
Co-authored-by: Nicola Timeus <[email protected]>
(cherry picked from commit 2263134)
  • Loading branch information
MMaiero authored and github-actions[bot] committed Apr 17, 2023
1 parent 964e694 commit dae4f29
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright (c) 2016, 2022 Eurotech and/or its affiliates and others
*
* Copyright (c) 2016, 2023 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
*
* SPDX-License-Identifier: EPL-2.0
*
*
* Contributors:
* Eurotech
* Amit Kumar Mondal
Expand All @@ -24,6 +24,7 @@
import static org.osgi.service.wireadmin.WireConstants.WIREADMIN_PRODUCER_PID;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashMap;
Expand Down Expand Up @@ -99,7 +100,7 @@ public class WireGraphServiceImpl implements ConfigurableComponent, WireGraphSer
* Binds the {@link WireAdmin} dependency
*
* @param wireAdmin
* the new {@link WireAdmin} service dependency
* the new {@link WireAdmin} service dependency
*/
public void bindWireAdmin(final WireAdmin wireAdmin) {
if (isNull(this.wireAdmin)) {
Expand All @@ -111,7 +112,7 @@ public void bindWireAdmin(final WireAdmin wireAdmin) {
* Unbinds {@link WireAdmin} dependency
*
* @param wireAdmin
* the new {@link WireAdmin} instance
* the new {@link WireAdmin} instance
*/
public void unbindWireAdmin(final WireAdmin wireAdmin) {
if (this.wireAdmin == wireAdmin) {
Expand Down Expand Up @@ -186,32 +187,29 @@ private boolean checkWireExistence(final String emitterServicePid, final String
final Wire[] wires = this.wireAdmin.getWires(null);
if (nonNull(wires)) {
for (final Wire w : wires) {

try {
final Dictionary<?, ?> props = w.getProperties();
if (emitterServicePid.equals(props.get(WIREADMIN_PRODUCER_PID))
&& receiverServicePid.equals(props.get(WIREADMIN_CONSUMER_PID))
&& emitterPort == (Integer) props.get(Constants.WIRE_EMITTER_PORT_PROP_NAME.value())
&& receiverPort == (Integer) props.get(Constants.WIRE_RECEIVER_PORT_PROP_NAME.value())) {
return true;
}
} catch (Exception e) {
continue;
final Dictionary<?, ?> props = w.getProperties();
if (emitterServicePid.equals(props.get(WIREADMIN_PRODUCER_PID))
&& receiverServicePid.equals(props.get(WIREADMIN_CONSUMER_PID))
&& emitterPort == (Integer) props.get(Constants.WIRE_EMITTER_PORT_PROP_NAME.value())
&& receiverPort == (Integer) props.get(Constants.WIRE_RECEIVER_PORT_PROP_NAME.value())) {
return true;
}
}
}
return false;

}

private void createConfiguration(final MultiportWireConfiguration conf) {
private void createConfiguration(Collection<ServiceReference<WireComponent>> wireComponentServiceReferences,
final MultiportWireConfiguration conf) {
requireNonNull(conf, "Wire Configuration cannot be null");

String emitterPid = conf.getEmitterPid();
String receiverPid = conf.getReceiverPid();
try {
final String emitterServicePid = getServicePidByKuraServicePid(emitterPid);
final String receiverServicePid = getServicePidByKuraServicePid(receiverPid);
final String emitterServicePid = getServicePidByKuraServicePid(wireComponentServiceReferences, emitterPid);
final String receiverServicePid = getServicePidByKuraServicePid(wireComponentServiceReferences,
receiverPid);
final int emitterPort = conf.getEmitterPort();
final int receiverPort = conf.getReceiverPort();
if (nonNull(emitterServicePid) && nonNull(receiverServicePid)) {
Expand All @@ -232,41 +230,22 @@ private void createConfiguration(final MultiportWireConfiguration conf) {
}

} catch (final InvalidSyntaxException e) {
logger.error("Error while creating wires...", e);
}
}

public MultiportWireConfiguration createWireConfigurationInternal(final String emitterPid, final String receiverPid,
final int emitterPort, final int receiverPort) throws KuraException {
if (!emitterPid.equals(receiverPid)) {
logger.info("Creating wire between {} and {}....", emitterPid, receiverPid);
final String emitterServicePid = getServicePidByKuraServicePid(emitterPid);
final String receiverServicePid = getServicePidByKuraServicePid(receiverPid);
if (isNull(emitterServicePid) || isNull(receiverServicePid)) {
throw new KuraException(KuraErrorCode.CONFIGURATION_ERROR,
"Unable to retrieve Factory PIDs of one of the provided Wire Components");
}
MultiportWireConfiguration conf = new MultiportWireConfiguration(emitterPid, receiverPid, emitterPort,
receiverPort);
WireGraphConfiguration wireGraphConfiguration = get();
final ArrayList<MultiportWireConfiguration> wireConfigurations = new ArrayList<>(
wireGraphConfiguration.getWireConfigurations());
wireConfigurations.add(conf);
update(new WireGraphConfiguration(wireGraphConfiguration.getWireComponentConfigurations(),
wireConfigurations));
logger.info("Creating wire between {} and {}....Done", emitterPid, receiverPid);
return conf;
logger.error("Error while creating wires configuration...", e);
}
return null;
}

/**
* Create the wires based on the provided wire configurations
*/
synchronized void createWires() {

for (final MultiportWireConfiguration wireConfig : this.currentConfiguration.getWireConfigurations()) {
createConfiguration(wireConfig);
try {
Collection<ServiceReference<WireComponent>> wireComponentServiceReferences = this.bundleContext
.getServiceReferences(WireComponent.class, null);
for (final MultiportWireConfiguration wireConfig : this.currentConfiguration.getWireConfigurations()) {
createConfiguration(wireComponentServiceReferences, wireConfig);
}
} catch (InvalidSyntaxException e) {
logger.error("Error while creating wires...", e);
}
}

Expand Down Expand Up @@ -542,7 +521,7 @@ private Set<String> getComponentsToDelete(List<WireComponentConfiguration> oldWi
final boolean hasChangedFactoryPid = newFactoryPid.isPresent() && oldFactoryPid.isPresent()
&& !oldFactoryPid.get().contentEquals(newFactoryPid.get());

return hasChangedFactoryPid || (hasBeenRemoved && !isWireAsset);
return hasChangedFactoryPid || hasBeenRemoved && !isWireAsset;
}), //
newWireComponentConfigurations.stream().filter(WireGraphServiceImpl::isWireAsset)//
).map(c -> c.getConfiguration().getPid()).collect(Collectors.toSet());
Expand Down Expand Up @@ -658,11 +637,17 @@ protected String marshal(Object object) {
return result;
}

private String getServicePidByKuraServicePid(
Collection<ServiceReference<WireComponent>> wireComponentServiceReferences, String kuraServicePid) {
return wireComponentServiceReferences.stream()
.filter(ref -> kuraServicePid.equals(ref.getProperty(KURA_SERVICE_PID)))
.map(ref -> (String) ref.getProperty(SERVICE_PID)).findAny().orElse(null);
}

protected String getServicePidByKuraServicePid(String kuraServicePid) {
try {
return this.bundleContext.getServiceReferences(WireComponent.class, null).stream()
.filter(ref -> kuraServicePid.equals(ref.getProperty(KURA_SERVICE_PID)))
.map(ref -> (String) ref.getProperty(SERVICE_PID)).findAny().orElse(null);
return getServicePidByKuraServicePid(this.bundleContext.getServiceReferences(WireComponent.class, null),
kuraServicePid);
} catch (InvalidSyntaxException e) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2022 Eurotech and/or its affiliates and others
* Copyright (c) 2017, 2023 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -14,14 +14,18 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

Expand All @@ -32,16 +36,20 @@
import org.eclipse.kura.core.testutil.TestUtil;
import org.eclipse.kura.internal.json.marshaller.unmarshaller.JsonMarshallUnmarshallImpl;
import org.eclipse.kura.wire.WireComponent;
import org.eclipse.kura.wire.graph.Constants;
import org.eclipse.kura.wire.graph.MultiportWireConfiguration;
import org.eclipse.kura.wire.graph.WireComponentConfiguration;
import org.eclipse.kura.wire.graph.WireGraphConfiguration;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.wireadmin.Wire;
import org.osgi.service.wireadmin.WireAdmin;
import org.osgi.service.wireadmin.WireConstants;
import org.osgi.util.tracker.ServiceTracker;

public class WireGraphServiceImplTest {
Expand Down Expand Up @@ -89,14 +97,42 @@ public void testCreateWires() throws NoSuchFieldException, InvalidSyntaxExceptio
String receiverPid = "receiverPid";

WireAdmin wireAdmin = mock(WireAdmin.class);
when(wireAdmin.createWire(eq(emitterPid), eq(receiverPid), any(Dictionary.class))).thenReturn(mock(Wire.class));
ComponentContext cc = mock(ComponentContext.class);
BundleContext bc = mock(BundleContext.class);
when(cc.getBundleContext()).thenReturn(bc);

ServiceReference<WireComponent> emitter = mock(ServiceReference.class);
when(emitter.getProperty("kura.service.pid")).thenReturn(emitterPid);
when(emitter.getProperty("service.pid")).thenReturn(emitterPid);
ServiceReference<WireComponent> receiver = mock(ServiceReference.class);
when(receiver.getProperty("kura.service.pid")).thenReturn(receiverPid);
when(receiver.getProperty("service.pid")).thenReturn(receiverPid);

Collection<ServiceReference<WireComponent>> wireComponentServiceReferences = new ArrayList();
wireComponentServiceReferences.add(emitter);
wireComponentServiceReferences.add(receiver);

when(bc.getServiceReferences(WireComponent.class, null)).thenReturn(wireComponentServiceReferences);

TestUtil.setFieldValue(wsi, "wireAdmin", wireAdmin);

wsi.activate(mock(ComponentContext.class), properties);
wsi.activate(cc, properties);

Wire wire = mock(Wire.class);
Dictionary<String, Object> props = new Hashtable<>();
props.put(Constants.WIRE_EMITTER_PORT_PROP_NAME.value(), 0);
props.put(Constants.WIRE_RECEIVER_PORT_PROP_NAME.value(), 0);
props.put(WireConstants.WIREADMIN_PRODUCER_PID, emitterPid);
props.put(WireConstants.WIREADMIN_CONSUMER_PID, receiverPid);
when(wire.getProperties()).thenReturn(props);
Wire[] wires = new Wire[] {wire};
when(wireAdmin.getWires(null)).thenReturn(wires);

wsi.createWires();

verify(servicePidMappings, times(1)).get(emitterPid);
verify(servicePidMappings, times(1)).get(receiverPid);
verify(wireAdmin, times(2)).getWires(null);
verify(wireAdmin, times(1)).createWire(eq(emitterPid), eq(receiverPid), any(Dictionary.class));
}

@Test
Expand Down

0 comments on commit dae4f29

Please sign in to comment.