What product/components do you use and which version/fix level are you on?
Cumulocity iot
Is your question related to the free trial, or to a production (customer) instance
dev tenant used for development
What are you trying to achieve? Please describe it in detail.
Trying to create multiple RestConnector objects (atleast 10-30) for a Multithreaded Class in a loop. But not able to create multiple instances of RestConnector. Please let me know the way to achieve this. In non-thread code inside the @Service class for a single POST methods using RestConnector it is working. But whenever I use RestConnector as @AutoWired inside my Runnable implemented thread logic class, it says RestConnector is null.
Do you get any error messages? Please provide a full error message screenshot and log file.
Have you installed all the latest fixes for the products and systems you are using?
why do you require multiple RestConnector “objects”?
Within a Runnable you @Autowired might not work as you expect. A code example would be helpful.
Usually you would need to pass the RestConnector bean into your Runnable, as you cannot inject it with the @Autowired annotation, AFAIK, hence it is null.
also the Java SDK itself only uses a single instance of RestConnector. So you should be good to reuse them in multiple threads. If you decide that you need multiple instances, make sure to not create them per-request They use this class internally: https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/Client.html
Thanks Harald for the reply. Yes that was my ideas to instantiate RestConnector per thread. But that didnt work by AutoWired. I will try to reuse RestConnector by passing the instance created by @Autowired once in my Runnable class. I will seek your help if needed again. Thanks.
Below are the snippets from the code. Kindly have a look at this.
Service Class code
@Service
public class RestClientServiceImpl3B {
@Autowired
public RestConnector restConnector1;
/* Concurrency starts here */
LOGGER.info("Before Threading ");
for (int icounter = 0; icounter < 2; icounter++) {
RunnableWorker r = new RunnableWorker(restConnector1);
Thread t1 = new Thread(r);
t1.start();
}
LOGGER.info("After Threading ");
/* Concurrency ends here */
Runnable Class code
public class RunnableWorker implements Runnable {
private RestConnector restConnector1;
public RunnableWorker(RestConnector restConnector1) {
this.restConnector1 = restConnector1;
}
private static final Logger LOGGER = LoggerFactory.getLogger(RunnableWorker.class);
@Override
public void run() {
String path = "https://cloud.iot.solenis.com/service/unify/measurement/measurements?dateFrom=2022-08-01T00:00:00.00Z&dateTo=2022-08-01T23:59:59.00Z&valueFragmentType=sol_onguardMeasurement&source=1437&pageSize=50000";
long startDateCheck = System.currentTimeMillis();
MeasurementCollectionRepresentation collectionRep = restConnector1.get(path,CumulocityMediaType.APPLICATION_JSON_TYPE, MeasurementCollectionRepresentation.class);
long endDateCheck = System.currentTimeMillis();
LOGGER.info("Time taken - check..check..check.. "+(endDateCheck-startDateCheck));
}
}
Error thrown is
Exception in thread “Thread-1” org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name ‘scopedTarget.tenantRestConnector’: Scope ‘tenant’ is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: Not within any context!
Hi Sethu,
the java.lang.IllegalStateException: Not within any context! exception clearly shows you that the new thread is not within any context.
Hence the RestController bean is there and ready, however no tenant-information/context is known.
This requires to pass the related tenant into the runnable as well and use the MicroserviceSubscriptionService (runForTenant or callForTenant methods) to get into the context again within the runnable (new thread).