Coder Social home page Coder Social logo

Comments (11)

MaryamZi avatar MaryamZi commented on September 28, 2024 1

Modified the code to access relevant annotations.

import ballerina/io;

type AnnotRecord record {|
    string value;
|};

type AnnotRecord1 record {|
    typedesc value;
|};

annotation AnnotRecord annot on type;
annotation AnnotRecord1 annot1 on service, type;

@annot {
    value: "T1"
}
public type Service service object {
    resource function get pet() returns string ;
};

listener Listener lst = new Listener(9090);

@annot1 {
    value: Service
}
service Service on lst  {
    resource function get pet() returns  string {
        return  "string";
    }
}

public class Listener {
    int port;
    Service? s = ();
    public function 'start() returns error? {
        Service s = <Service> self.s;
        AnnotRecord1? annot = (typeof s).@annot1;
        io:println("start: ", annot);
        if annot is AnnotRecord1 {
            io:println(Service.@annot);
            io:println(annot.value.@annot);
        }
    }

    public function gracefulStop() returns error? {
    }

    public function immediateStop() returns error? {
    }

    public function detach(Service s) returns error? {
    }

    public function attach(Service s, string[]? name = ()) returns error? {
        self.s = s;
        AnnotRecord1? annot = (typeof s).@annot1;
        io:println("attach: ", annot);
        if annot is AnnotRecord1 {
            io:println(Service.@annot);
            io:println(annot.value.@annot);
        }
    }

    public function init(int port) {
        self.port = port;
    }
}
Running executable

attach: {"value":typedesc Service}


start: {"value":typedesc Service}
{"value":"T1"}
{"value":"T1"}

The annotation is available at start. Assuming this translates to native code also, is accessing annotations at start an option for now, @TharmiganK?

from ballerina-lang.

chiranSachintha avatar chiranSachintha commented on September 28, 2024

This issue occurs when a service calls the listener from the compiler before setting the annotations to the types. (We are not generating type descriptors for the service types. Therefore, we need to retain the annotations in the type for now). With the following example, we can generate the issue.

import ballerina/io;

type AnnotRecord record {|
    string value;
|};

type AnnotRecord1 record {|
    typedesc value;
|};

annotation AnnotRecord annot on type;
annotation AnnotRecord1 annot1 on service, type;



@annot {
    value: "T1"
}
public type Service service object {
    resource function get pet() returns string ;
};



listener Listener lst = new Listener(9090);

@annot1 {
    value: Service
}
service Service on lst  {
    resource function get pet() returns  string {
        return  "string";
    }
}

public class Listener {
    int port;
    public function 'start() returns error? {
    }

    public function gracefulStop() returns error? {
    }

    public function immediateStop() returns error? {
    }

    public function detach(service object {} s) returns error? {
    }

    public function attach(service object {} s, string[]? name = ()) returns error? {
        AnnotRecord1? annot = (typeof s).@annot1;
        io:println(annot);
        if annot is AnnotRecord1 {
            io:println((typeof Service).@annot1);
            io:println((typeof (annot.value)).@annot);
        }
    }

    public function init(int port) {
        self.port = port;
    }
}

from ballerina-lang.

MaryamZi avatar MaryamZi commented on September 28, 2024

Is this a duplicate of #33594 then? Are they accessible in the start method?

We tried fixing the original issue back then, but deferred due to complexity of a workaround vs going with the typedesc change.

from ballerina-lang.

TharmiganK avatar TharmiganK commented on September 28, 2024

The annotation is available at start. Assuming this translates to native code also, is accessing annotations at start an option for now?

Will check on this

from ballerina-lang.

chiranSachintha avatar chiranSachintha commented on September 28, 2024

Is this a duplicate of #33594 then? Are they accessible in the start method?

We tried fixing the original issue back then, but deferred due to complexity of a workaround vs going with the typedesc change.

Yes.

from ballerina-lang.

TharmiganK avatar TharmiganK commented on September 28, 2024

@MaryamZi I moved the logic to start and the service level annotations are now present for the service types defined in the same package (if I defined the service type in a different package and import, the annotations are present in attach and start)

But the original issue is still there where I cannot get the resource level annotations. The following is a reduced ballerina code which represents my actual use case:

import ballerina/io;

type ResourceAnnotation record {
    string value;
};

type ParameterAnnotation record {
    string value;
};

type ServiceAnnotation record {
    string value?;
    typedesc<ServiceContract> serviceContractType?;
};

annotation ResourceAnnotation ResourceConfig on function;
annotation ParameterAnnotation ParamConfig on parameter;
annotation ServiceAnnotation ServiceConfig on service, type;

public type Service service object {
};

public type ServiceContract service object {
     *Service;
};

public type User record {|
    int id;
    string name;
    string email;
|};

@ServiceConfig {
    value: "users-service-contract"
}
public type UsersService service object {
    *ServiceContract;

    @ResourceConfig {value: "get-users"}
    resource function post users(@ParamConfig {value: "payload-param"} User user) returns User|error;
};

public class Listener {

    Service? s = ();

    public function 'start() returns error? {
        ServiceAnnotation? serviceConfig = (typeof self.s).@ServiceConfig;
        io:println("self-start: ", serviceConfig);
        if serviceConfig is ServiceAnnotation {
            io:println("self-start: ", UsersService.@ServiceConfig);
            typedesc<ServiceContract>? serviceContractType = serviceConfig.serviceContractType;
            io:println("self-start: ", serviceContractType);
            if serviceContractType is typedesc<ServiceContract> {
                io:println("self-start: ", serviceContractType.@ServiceConfig);
            }
        }
        // Need to access the resource level and resource parameter level annotations here
    }

    public function gracefulStop() returns error? {
    }

    public function immediateStop() returns error? {
    }

    public function detach(Service s) returns error? {
    }

    public function attach(Service s, string[]? name = ()) returns error? {
        self.s = s;
        ServiceAnnotation? serviceConfig = (typeof s).@ServiceConfig;
        io:println("self-attach: ", serviceConfig);
        if serviceConfig is ServiceAnnotation { 
            io:println("self-attach: ", UsersService.@ServiceConfig);
            typedesc<ServiceContract>? serviceContractType = serviceConfig.serviceContractType;
            io:println("self-attach: ", serviceContractType);
            if serviceContractType is typedesc<ServiceContract> {
                io:println("self-attach: ", serviceContractType.@ServiceConfig);
            }
        }
    }

    public function init(int port) {
    }
}

@ServiceConfig {
    serviceContractType: UsersService
}
service UsersService on new Listener(8080) {
    resource function post users(User user) returns User|error {
        return user;
    }
}

Note: Please note the resource level and resource parameter level annotations in the service contract type - UsersService

from ballerina-lang.

chiranSachintha avatar chiranSachintha commented on September 28, 2024

This is a bug in the compiler. The issue is that we added those annotations to the annotation map, but at runtime, we didn't apply these annotations to the type associated with the resource functions and parameters. We only set the annotations which attached to the service type. (As a solution, we need to add those annotations to their respective types by calling the processAnnotation function.) @MaryamZi

from ballerina-lang.

MaryamZi avatar MaryamZi commented on September 28, 2024

Seems to be an issue at runtime rather.

The check at https://github.com/ballerina-platform/ballerina-lang/blob/v2201.9.2/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/AnnotationUtils.java#L61 is no longer sufficient with type reference types.

from ballerina-lang.

MaryamZi avatar MaryamZi commented on September 28, 2024

Let's use

  • #33594 to track the original issue and
  • #43122 to track the new issue (tagging this for U10)

from ballerina-lang.

MaryamZi avatar MaryamZi commented on September 28, 2024

Let's use

Closing this since this was/is tracked in other issues.

from ballerina-lang.

github-actions avatar github-actions commented on September 28, 2024

This issue is NOT closed with a proper Reason/ label. Make sure to add proper reason label before closing. Please add or leave a comment with the proper reason label now.

      - Reason/EngineeringMistake - The issue occurred due to a mistake made in the past.
      - Reason/Regression - The issue has introduced a regression.
      - Reason/MultipleComponentInteraction - Issue occured due to interactions in multiple components.
      - Reason/Complex - Issue occurred due to complex scenario.
      - Reason/Invalid - Issue is invalid.
      - Reason/Other - None of the above cases.

from ballerina-lang.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.