text:
require 'bitcoin/script'

module Bitcoin
  module Protocol

    class Tx

      # transaction hash
      attr_reader :hash

      # inputs (Array of TxIn)
      attr_reader :in

      # outputs (Array of TxOut)
      attr_reader :out

      # raw protocol payload
      attr_reader :payload

      # version (usually 1)
      attr_accessor :ver

      # lock time
      attr_accessor :lock_time

      # parsed / evaluated input scripts cached for later use
      attr_reader :scripts

      alias :inputs  :in
      alias :outputs :out

      # compare to another tx
      def ==(other)
        @hash == other.hash
      end

      # return the tx hash in binary format
      def binary_hash
        @binary_hash ||= [@hash].pack("H*").reverse
      end

      # create tx from raw binary +data+
      def initialize(data=nil)
        @ver, @lock_time, @in, @out, @scripts = 1, 0, [], [], []
        @enable_bitcoinconsensus = !!ENV['USE_BITCOINCONSENSUS']
        parse_data_from_io(data) if data
      end

      # generate the tx hash for given +payload+ in hex format
      def hash_from_payload(payload)
        Digest::SHA256.digest(Digest::SHA256.digest( payload )).reverse_hth
      end
      alias generate_hash hash_from_payload

      # add an input
      def add_in(input); (@in ||= []) << input; end

      # add an output
      def add_out(output); (@out ||= []) << output; end

      # parse raw binary data
      def parse_data_from_io(data)
        buf = data.is_a?(String) ? StringIO.new(data) : data
        payload_start = buf.pos

        @ver = buf.read(4).unpack("V")[0]

        return false if buf.eof?

        in_size = Protocol.unpack_var_int_from_io(buf)
        @in = []
        in_size.times{
          break if buf.eof?
          @in << TxIn.from_io(buf)
        }

        return false if buf.eof?

        out_size = Protocol.unpack_var_int_from_io(buf)
        @out = []
        out_size.times{
          break if buf.eof?
          @out << TxOut.from_io(buf)
        }

        return false if buf.eof?

        @lock_time = buf.read(4).unpack("V")[0]

        payload_end = buf.pos;
        buf.seek(payload_start)
        @payload = buf.read( payload_end-payload_start )
        @hash = hash_from_payload(@payload)

        if buf.eof?
          true
        else
          data.is_a?(StringIO) ? buf : buf.read
        end
      end

      alias :parse_data  :parse_data_from_io

      # output transaction in raw binary format
      def to_payload
        pin = ""
        @in.each{|input| pin << input.to_payload }
        pout = ""
        @out.each{|output| pout << output.to_payload }

        [@ver].pack("V") << Protocol.pack_var_int(@in.size) << pin << Protocol.pack_var_int(@out.size) << pout << [@lock_time].pack("V")
      end

      SIGHASH_TYPE = { all: 1, none: 2, single: 3, anyonecanpay: 128 }

      # generate a signature hash for input +input_idx+.
      # either pass the +outpoint_tx+ or the +script_pubkey+ directly.
      def signature_hash_for_input(input_idx, subscript, hash_type=nil)
        # https://github.com/bitcoin/bitcoin/blob/e071a3f6c06f41068ad17134189a4ac3073ef76b/script.cpp#L834
        # http://code.google.com/p/bitcoinj/source/browse/trunk/src/com/google/bitcoin/core/Script.java#318
        # https://en.bitcoin.it/wiki/OP_CHECKSIG#How_it_works
        # https://github.com/bitcoin/bitcoin/blob/c2e8c8acd8ae0c94c70b59f55169841ad195bb99/src/script.cpp#L1058
        # https://en.bitcoin.it/wiki/OP_CHECKSIG

        # Note: BitcoinQT checks if input_idx >= @in.size and returns 1 with an error message.
        # But this check is never actually useful because BitcoinQT would crash
        # right before VerifyScript if input index is out of bounds (inside CScriptCheck::operator()()).
        # That's why we don't need to do such a check here.
        #
        # However, if you look at the case SIGHASH_TYPE[:single] below, we must
        # return 1 because it's possible to have more inputs than outputs and BitcoinQT returns 1 as well.
        return "\x01".ljust(32, "\x00") if input_idx >= @in.size # ERROR: SignatureHash() : input_idx=%d out of range

        hash_type ||= SIGHASH_TYPE[:all]

        pin  = @in.map.with_index{|input,idx|
          if idx == input_idx
            subscript = subscript.out[ input.prev_out_index ].script if subscript.respond_to?(:out) # legacy api (outpoint_tx)
            input.to_payload(subscript)
          else
            case (hash_type & 0x1f)
            when SIGHASH_TYPE[:none];   input.to_payload("", "\x00\x00\x00\x00")
            when SIGHASH_TYPE[:single]; input.to_payload("", "\x00\x00\x00\x00")
            else;                       input.to_payload("")
            end
          end
        }

        pout = @out.map(&:to_payload)
        in_size, out_size = Protocol.pack_var_int(@in.size), Protocol.pack_var_int(@out.size)

        case (hash_type & 0x1f)
        when SIGHASH_TYPE[:none]
          pout = ""
          out_size = Protocol.pack_var_int(0)
        when SIGHASH_TYPE[:single]
          return "\x01".ljust(32, "\x00") if input_idx >= @out.size # ERROR: SignatureHash() : input_idx=%d out of range (SIGHASH_SINGLE)
          pout = @out[0...(input_idx+1)].map.with_index{|out,idx| (idx==input_idx) ? out.to_payload : out.to_null_payload }.join
          out_size = Protocol.pack_var_int(input_idx+1)
        end

        if (hash_type & SIGHASH_TYPE[:anyonecanpay]) != 0
          in_size, pin = Protocol.pack_var_int(1), [ pin[input_idx] ]
        end

        buf = [ [@ver].pack("V"), in_size, pin, out_size, pout, [@lock_time, hash_type].pack("VV") ].join
        Digest::SHA256.digest( Digest::SHA256.digest( buf ) )
      end

      # verify input signature +in_idx+ against the corresponding
      # output in +outpoint_tx+
      # outpoint
      #
      # options are: verify_sigpushonly, verify_minimaldata, verify_cleanstack, verify_dersig, verify_low_s, verify_strictenc
      def verify_input_signature(in_idx, outpoint_tx_or_script, block_timestamp=Time.now.to_i, opts={})
        if @enable_bitcoinconsensus
          return bitcoinconsensus_verify_script(in_idx, outpoint_tx_or_script, block_timestamp, opts)
        end

        outpoint_idx  = @in[in_idx].prev_out_index
        script_sig    = @in[in_idx].script_sig

        # If given an entire previous transaction, take the script from it
        script_pubkey = if outpoint_tx_or_script.respond_to?(:out)
          outpoint_tx_or_script.out[outpoint_idx].pk_script
        else
          # Otherwise, it's already a script.
          outpoint_tx_or_script
        end

        @scripts[in_idx] = Bitcoin::Script.new(script_sig, script_pubkey)
        return false if opts[:verify_sigpushonly] && !@scripts[in_idx].is_push_only?(script_sig)
        return false if opts[:verify_minimaldata] && !@scripts[in_idx].pushes_are_canonical?
        sig_valid = @scripts[in_idx].run(block_timestamp, opts) do |pubkey,sig,hash_type,subscript|
          hash = signature_hash_for_input(in_idx, subscript, hash_type)
          Bitcoin.verify_signature( hash, sig, pubkey.unpack("H*")[0] )
        end
        # BIP62 rule #6
        return false if opts[:verify_cleanstack] && !@scripts[in_idx].stack.empty?

        return sig_valid
      end

      def bitcoinconsensus_verify_script(in_idx, outpoint_tx_or_script, block_timestamp=Time.now.to_i, opts={})
        raise "Bitcoin::BitcoinConsensus shared library not found" unless Bitcoin::BitcoinConsensus.lib_available?

        # If given an entire previous transaction, take the script from it
        script_pubkey = if outpoint_tx_or_script.respond_to?(:out)
          outpoint_idx  = @in[in_idx].prev_out_index
          outpoint_tx_or_script.out[outpoint_idx].pk_script
        else
          # Otherwise, it's already a script.
          outpoint_tx_or_script
        end

        flags  = Bitcoin::BitcoinConsensus::SCRIPT_VERIFY_NONE
        flags |= Bitcoin::BitcoinConsensus::SCRIPT_VERIFY_P2SH        if block_timestamp >= 1333238400
        flags |= Bitcoin::BitcoinConsensus::SCRIPT_VERIFY_SIGPUSHONLY if opts[:verify_sigpushonly]
        flags |= Bitcoin::BitcoinConsensus::SCRIPT_VERIFY_MINIMALDATA if opts[:verify_minimaldata]
        flags |= Bitcoin::BitcoinConsensus::SCRIPT_VERIFY_CLEANSTACK  if opts[:verify_cleanstack]
        flags |= Bitcoin::BitcoinConsensus::SCRIPT_VERIFY_LOW_S       if opts[:verify_low_s]

        payload ||= to_payload
        Bitcoin::BitcoinConsensus.verify_script(in_idx, script_pubkey, payload, flags)
      end

      # convert to ruby hash (see also #from_hash)
      def to_hash(options = {})
        @hash ||= hash_from_payload(to_payload)
        h = {
          'hash' => @hash, 'ver' => @ver, # 'nid' => normalized_hash,
          'vin_sz' => @in.size, 'vout_sz' => @out.size,
          'lock_time' => @lock_time, 'size' => (@payload ||= to_payload).bytesize,
          'in'  =>  @in.map{|i| i.to_hash(options) },
          'out' => @out.map{|o| o.to_hash(options) }
        }
        h['nid'] = normalized_hash  if options[:with_nid]
        h
      end

      # generates rawblock json as seen in the block explorer.
      def to_json(options = {:space => ''}, *a)
        JSON.pretty_generate( to_hash(options), options )
      end

      # write json representation to a file
      # (see also #to_json)
      def to_json_file(path)
        File.open(path, 'wb'){|f| f.print to_json; }
      end

      # parse ruby hash (see also #to_hash)
      def self.from_hash(h)
        tx = new(nil)
        tx.ver, tx.lock_time = (h['ver'] || h['version']), h['lock_time']
        ins  = h['in']  || h['inputs']
        outs = h['out'] || h['outputs']
        ins .each{|input|   tx.add_in  TxIn.from_hash(input)   }
        outs.each{|output|  tx.add_out TxOut.from_hash(output) }
        tx.instance_eval{ @hash = hash_from_payload(@payload = to_payload) }
        tx
      end

      # convert ruby hash to raw binary
      def self.binary_from_hash(h); from_hash(h).to_payload; end

      # parse json representation
      def self.from_json(json_string); from_hash( JSON.load(json_string) ); end

      # convert json representation to raw binary
      def self.binary_from_json(json_string); from_json(json_string).to_payload; end

      # read binary block from a file
      def self.from_file(path); new( Bitcoin::Protocol.read_binary_file(path) ); end

      # read json block from a file
      def self.from_json_file(path); from_json( Bitcoin::Protocol.read_binary_file(path) ); end

      def size
        payload.bytesize
      end

      # Checks if transaction is final taking into account height and time
      # of a block in which it is located (or about to be included if it's unconfirmed tx).
      def is_final?(block_height, block_time)
        # No time lock - tx is final.
        return true if lock_time == 0

        # Time based nLockTime implemented in 0.1.6
        # If lock_time is below the magic threshold treat it as a block height.
        # If lock_time is above the threshold, it's a unix timestamp.
        return true if lock_time < (lock_time < Bitcoin::LOCKTIME_THRESHOLD ? block_height : block_time)

        inputs.each{|input| return false if !input.is_final? }

        return true
      end

      def legacy_sigops_count
        # Note: input scripts normally never have any opcodes since every input script
        # can be statically reduced to a pushdata-only script.
        # However, anyone is allowed to create a non-standard transaction with any opcodes in the inputs.
        count = 0
        self.in.each do |txin|
          count += Bitcoin::Script.new(txin.script_sig).sigops_count_accurate(false)
        end
        self.out.each do |txout|
          count += Bitcoin::Script.new(txout.pk_script).sigops_count_accurate(false)
        end
        count
      end

      DEFAULT_BLOCK_PRIORITY_SIZE = 27000

      def minimum_relay_fee; calculate_minimum_fee(allow_free=true, :relay); end
      def minimum_block_fee; calculate_minimum_fee(allow_free=true, :block); end

      def calculate_minimum_fee(allow_free=true, mode=:block)
        # Base fee is either nMinTxFee or nMinRelayTxFee
        base_fee  = (mode == :relay) ? Bitcoin.network[:min_relay_tx_fee] : Bitcoin.network[:min_tx_fee]
        tx_size   = to_payload.bytesize
        min_fee   = (1 + tx_size / 1_000) * base_fee

        if allow_free
          # There is a free transaction area in blocks created by most miners,
          # * If we are relaying we allow transactions up to DEFAULT_BLOCK_PRIORITY_SIZE - 1000
          #   to be considered to fall into this category. We don't want to encourage sending
          #   multiple transactions instead of one big transaction to avoid fees.
          # * If we are creating a transaction we allow transactions up to 1,000 bytes
          #   to be considered safe and assume they can likely make it into this section.
          min_fee = 0 if tx_size < (mode == :block ? Bitcoin.network[:free_tx_bytes] : DEFAULT_BLOCK_PRIORITY_SIZE - 1_000)
        end

        # This code can be removed after enough miners have upgraded to version 0.9.
        # Until then, be safe when sending and require a fee if any output is less than CENT
        if min_fee < base_fee && mode == :block
          outputs.each do |output|
            if output.value < Bitcoin.network[:dust]
              # If per dust fee, then we add min fee for each output less than dust.
              # Otherwise, we set to min fee if there is any output less than dust.
              if Bitcoin.network[:per_dust_fee]
                min_fee += base_fee
              else
                min_fee = base_fee
                break
              end
            end
          end
        end

        min_fee = Bitcoin::network[:max_money] unless min_fee.between?(0, Bitcoin::network[:max_money])
        min_fee
      end

      def is_coinbase?
        inputs.size == 1 and inputs.first.coinbase?
      end

      def normalized_hash
        signature_hash_for_input(-1, nil, SIGHASH_TYPE[:all]).reverse.hth
      end
      alias :nhash :normalized_hash

    end
  end
end


text:
import { URL } from 'node:url';
import type { FetchConfig, FetchRequest, RestApiResponse } from 'rest-api-support';
import EventSource from 'eventsource';
import { ServiceError, ServiceErrorSpec } from '../error';

import type {
  ServiceExpress,
  ServiceLike,
  ServiceLocals,
} from '../types';
import type { ServiceConfiguration } from '../config/schema';

class CustomEventSource extends EventSource {
  private activeListeners: Array<{ handler: (data: any) => void; name: string }> = [];

  addEventListener(name: string, handler: (data: any) => void): this {
    super.addEventListener(name, handler);
    this.activeListeners.push({ name, handler });
    return this;
  }

  removeAllListeners() {
    this.activeListeners.forEach((l) => {
      super.removeEventListener(l.name as keyof EventSourceEventMap, l.handler);
    });
  }
}

/**
 * Return a factory that will make instances of an OpenAPI/Swagger client for each request
 */
export function createServiceInterface<ServiceType>(
  service: ServiceExpress,
  name: string,
  Implementation: { new (c: FetchConfig): ServiceType },
): ServiceType {
  const appConfig = service.locals.config;
  const config = {
    ...(appConfig.get('connections:default') || {}),
    ...(appConfig.get(`connections:${name}`) || {}),
  } as ServiceConfiguration;
  const protocol = config?.protocol || 'http';
  const port = config?.port || 8000;
  const host = config?.host || name;
  const baseUrl = `${protocol}${protocol.endsWith(':') ? '//' : '://'}${host}:${port}${
    config?.basePath || ''
  }`;

  const fetchConfig: FetchConfig = {
    fetch,
    AbortController,
    EventSource: CustomEventSource,
    FormData,
    baseUrl,
  };

  // In development, it can be useful to route requests through
  // a centralized local proxy (we use https://github.com/gas-buddy/container-proxy).
  // This allows you to run a subset of services locally and route the rest
  // of the requests to another (typically remote) environment.
  if (config?.proxy) {
    const proxyUrl = new URL(config.proxy);
    const proxyPort = proxyUrl.protocol === 'https:' ? '8443' : '8000';

    fetchConfig.requestInterceptor = (params: FetchRequest) => {
      const parsedUrl = new URL(params.url);
      const proto = parsedUrl.protocol.replace(/:$/, '');
      const defaultPort = proto === 'https' ? 8443 : 8000;
      const headers: FetchRequest['headers'] = {};
      headers.host = `${proto}.${parsedUrl.hostname}.${port || defaultPort}`;
      headers.source = service.locals.name;
      parsedUrl.hostname = proxyUrl.hostname;
      parsedUrl.protocol = proxyUrl.protocol;
      parsedUrl.port = proxyUrl.port || proxyPort;
      // eslint-disable-next-line no-param-reassign
      params.headers = params.headers || {};
      Object.assign(params.headers, headers);
      // eslint-disable-next-line no-param-reassign
      params.url = parsedUrl.href;
    };
  }

  return new Implementation(fetchConfig);
}

interface SpecWithMessage extends ServiceErrorSpec {
  message?: string;
}

function readResponse<
  SLocals extends ServiceLocals,
  AppType extends ServiceLike<SLocals>,
  ResType extends RestApiResponse<number, any>,
>(
  app: AppType,
  response: ResType,
  errorSpec?: SpecWithMessage,
): Extract<ResType, { responseType: 'response' }> {
  if (response.responseType === 'response') {
    return response as Extract<ResType, { responseType: 'response' }>;
  }
  const { message, ...spec } = errorSpec || {};
  throw new ServiceError(
    app,
    message || response.body.message || 'Internal Error',
    {
      status: response.status,
      ...spec,
    },
  );
}

export async function throwOrGetResponse<
  SLocals extends ServiceLocals,
  AppType extends ServiceLike<SLocals>,
  ResType extends RestApiResponse<number, any>,
>(
  app: AppType,
  exec: () => Promise<ResType>,
  errorSpec?: SpecWithMessage,
): Promise<Extract<ResType, { responseType: 'response' }>> {
  const response = await exec();
  return readResponse(app, response, errorSpec);
}

redpajama_set_name: RedPajamaGithub


text:
This project contains the back end applications to be used in conjunction with the Pool Doctors demo application for Genero Mobile.

This project consists of a a number of applications.

The applications are ...

## pool_doctors_server

This is the application that contains the web services that are used by the mobile application to interface with the back end database.

## pool_doctors_enquiry

This is an applicaton that allows you to view the data in back end database.  The left hand side consists of a list of jobs in the database.

![Screen Shot 2021-01-22 at 15 08 31](https://user-images.githubusercontent.com/13615993/105436305-deb95c80-5cc3-11eb-97af-022202b7b82e.png)

The right hand side consists of a number of collapsible group boxes that allow you to view the dataa in the child tables for each job.  To view the data for that job, expand the appropriate group box

![Screen Shot 2021-01-22 at 15 08 51](https://user-images.githubusercontent.com/13615993/105436316-e24ce380-5cc3-11eb-8ded-b68dbdadae7a.png)

There are 3 actions

* Refresh - Redo the selects from the database
* Web Services - This will run the pool_doctors_service_test application that you can use to test the various Web Services
* Delete - Delete the data for the currently selected job

## pool_doctors_service_test

Allows you to do rudimentary tests of the various web services from the back end.  It will display any results to stdout so is intended to be run from Geneor Studio so that output appears in the output panel.  Similarly some of the input parameters are hard-coded e.g. customer_get() is hard-coded to AKL028, product_get is hard-coded to "WIDESKIM"

## pool_doctors_service_test_create

Tests the generation of the 4gl client code that is used to call the web services

## pool_doctors_create_db

Creates the back end database and populates some data into the customer and product tables

## Usage

The intended usage is that you will

1. Run pool_doctors_create_db to create the database on your backend
2. Start pool_doctors_server to start the back end web services exposing the data in this database
3. Start pool_doctors_enquiry to view the data in the back end database
4. From pool_doctors_enquiry you can click Web Services button to execute a web service and click Refresh button to update your view of the database.  A good test as part of this is to i) click Web Services->Create Random Job ii) click Refresh and observe that the number of jobs in the list on the left will grow by one


text:
namespace SwissAcademic.Addons.TomatoTimerAddon
{
    public enum TimerState
    {
        Stopped,
        Running,
        Pausing,
        Walking
    }
}


text:
#import "NSObject-Protocol.h"

@protocol VKMapViewDelegate <NSObject>

@optional
- (void)mapView:(id)arg1 willTransitionFrom:(long long)arg2 to:(long long)arg3 duration:(double)arg4;
- (void)mapView:(id)arg1 selectedLabelMarkerWillDisappear:(id)arg2;
- (void)mapView:(id)arg1 didFinishChangingMapDisplayStyle:(long long)arg2;
- (void)mapView:(id)arg1 canShowFlyoverDidChange:(_Bool)arg2;
- (void)mapView:(id)arg1 showingFlyoverDidChange:(_Bool)arg2;
- (void)mapView:(id)arg1 canEnter3DModeDidChange:(_Bool)arg2;
- (void)mapView:(id)arg1 didBecomePitched:(_Bool)arg2;
- (id)mapView:(id)arg1 painterForOverlay:(id)arg2;
- (void)mapView:(id)arg1 didFinishAddingAnnotationMarkers:(id)arg2;
- (void)mapView:(id)arg1 didAnimateInAnnotationMarkers:(id)arg2;
- (void)mapView:(id)arg1 willAnimateInAnnotationMarkers:(id)arg2;
- (void)mapView:(id)arg1 annotationMarker:(id)arg2 didChangeDragState:(long long)arg3 fromOldState:(long long)arg4;
- (void)mapView:(id)arg1 didAddAnnotationMarkers:(id)arg2;
- (id)mapView:(id)arg1 presentationForAnnotation:(id)arg2;
- (void)mapViewDidBecomeFullyDrawn:(id)arg1 hasFailedTiles:(_Bool)arg2;
- (void)mapViewDidBecomePartiallyDrawn:(id)arg1;
- (void)mapViewDidStopRegionAnimation:(id)arg1 completed:(_Bool)arg2;
- (void)mapViewWillStartRegionAnimation:(id)arg1;
- (void)mapViewDidDraw:(id)arg1;
- (void)mapViewDidChangeVisibleRegion:(id)arg1;
- (void)mapViewDidFailLoadingTiles:(id)arg1 withError:(id)arg2;
- (void)mapViewDidFinishLoadingTiles:(id)arg1;
- (void)mapViewDidStartLoadingTiles:(id)arg1;
@end


text:
import netaddr

from apicapi import apic_manager
from keystoneclient.v2_0 import client as keyclient
from neutron.common import constants as n_constants
from neutron.common import exceptions as n_exc
from neutron.common import rpc as n_rpc
from neutron.common import topics
from neutron import context as nctx
from neutron.extensions import portbindings
from neutron import manager
from neutron.openstack.common import lockutils
from neutron.openstack.common import log as logging
from neutron.plugins.ml2.drivers.cisco.apic import apic_model
from neutron.plugins.ml2.drivers.cisco.apic import config
from opflexagent import constants as ofcst
from opflexagent import rpc
from oslo.config import cfg

from gbpservice.neutron.db.grouppolicy import group_policy_mapping_db as gpdb
from gbpservice.neutron.extensions import group_policy as gpolicy
from gbpservice.neutron.services.grouppolicy.common import constants as g_const
from gbpservice.neutron.services.grouppolicy.common import exceptions as gpexc
from gbpservice.neutron.services.grouppolicy.drivers import (
    resource_mapping as api)
from gbpservice.neutron.services.grouppolicy.drivers.cisco.apic import (
    nova_client as nclient)
from gbpservice.neutron.services.grouppolicy import group_policy_context

LOG = logging.getLogger(__name__)
UNMANAGED_SEGMENT = _("External Segment %s is not managed by APIC mapping "
                      "driver.")

class PolicyRuleUpdateNotSupportedOnApicDriver(gpexc.GroupPolicyBadRequest):
    message = _("Policy rule update is not supported on APIC GBP"
                "driver.")

class ExactlyOneActionPerRuleIsSupportedOnApicDriver(
        gpexc.GroupPolicyBadRequest):
    message = _("Exactly one action per rule is supported on APIC GBP driver.")

class OnlyOneL3PolicyIsAllowedPerExternalSegment(gpexc.GroupPolicyBadRequest):
    message = _("Only one L3 Policy per ES is supported on APIC GBP driver.")

class OnlyOneAddressIsAllowedPerExternalSegment(gpexc.GroupPolicyBadRequest):
    message = _("Only one ip address on each ES is supported on "
                "APIC GBP driver.")

class NoAddressConfiguredOnExternalSegment(gpexc.GroupPolicyBadRequest):
    message = _("L3 Policy %(l3p_id)s has no address configured on "
                "External Segment %(es_id)s")

class PATNotSupportedByApicDriver(gpexc.GroupPolicyBadRequest):
    message = _("Port address translation is not supported by APIC driver.")

class SharedAttributeUpdateNotSupportedOnApic(gpexc.GroupPolicyBadRequest):
    message = _("Resource shared attribute update not supported on APIC "
                "GBP driver for resource of type %(type)s")

class ExplicitSubnetAssociationNotSupported(gpexc.GroupPolicyBadRequest):
    message = _("Explicit subnet association not supported by APIC driver.")

class HierarchicalContractsNotSupported(gpexc.GroupPolicyBadRequest):
    message = _("Hierarchical contracts not supported by APIC driver.")

REVERSE_PREFIX = 'reverse-'
SHADOW_PREFIX = 'Shd-'
SERVICE_PREFIX = 'Svc-'
IMPLICIT_PREFIX = 'implicit-'
ANY_PREFIX = 'any-'
PROMISCUOUS_SUFFIX = 'promiscuous'
APIC_OWNED = 'apic_owned_'
PROMISCUOUS_TYPES = [n_constants.DEVICE_OWNER_DHCP,
                     n_constants.DEVICE_OWNER_LOADBALANCER]
ALLOWING_ACTIONS = [g_const.GP_ACTION_ALLOW, g_const.GP_ACTION_REDIRECT]
REVERTIBLE_PROTOCOLS = [n_constants.PROTO_NAME_TCP.lower()]

class ApicMappingDriver(api.ResourceMappingDriver):
    """Apic Mapping driver for Group Policy plugin.

    This driver implements group policy semantics by mapping group
    policy resources to various other neutron resources, and leverages
    Cisco APIC's backend for enforcing the policies.
    """

    me = None
    manager = None

    @staticmethod
    def get_apic_manager(client=True):
        if not ApicMappingDriver.manager:
            apic_config = cfg.CONF.ml2_cisco_apic
            network_config = {
                'vlan_ranges': cfg.CONF.ml2_type_vlan.network_vlan_ranges,
                'vni_ranges': cfg.CONF.ml2_type_vxlan.vni_ranges,
                'switch_dict': config.create_switch_dictionary(),
                'vpc_dict': config.create_vpc_dictionary(),
                'external_network_dict':
                    config.create_external_network_dictionary(),
            }
            apic_system_id = cfg.CONF.apic_system_id
            keyclient_param = keyclient if client else None
            keystone_authtoken = (cfg.CONF.keystone_authtoken if client else
                                  None)
            ApicMappingDriver.manager = apic_manager.APICManager(
                apic_model.ApicDbModel(), logging, network_config, apic_config,
                keyclient_param, keystone_authtoken, apic_system_id)
            ApicMappingDriver.manager.ensure_infra_created_on_apic()
            ApicMappingDriver.manager.ensure_bgp_pod_policy_created_on_apic()
        return ApicMappingDriver.manager

    def initialize(self):
        super(ApicMappingDriver, self).initialize()
        self._setup_rpc_listeners()
        self._setup_rpc()
        self.apic_manager = ApicMappingDriver.get_apic_manager()
        self.name_mapper = self.apic_manager.apic_mapper
        self._gbp_plugin = None
        ApicMappingDriver.me = self

    def _setup_rpc_listeners(self):
        self.endpoints = [rpc.GBPServerRpcCallback(self)]
        self.topic = rpc.TOPIC_OPFLEX
        self.conn = n_rpc.create_connection(new=True)
        self.conn.create_consumer(self.topic, self.endpoints,
                                  fanout=False)
        return self.conn.consume_in_threads()

    def _setup_rpc(self):
        self.notifier = rpc.AgentNotifierApi(topics.AGENT)

    @property
    def gbp_plugin(self):
        if not self._gbp_plugin:
            self._gbp_plugin = (manager.NeutronManager.get_service_plugins()
                                .get("GROUP_POLICY"))
        return self._gbp_plugin

    # RPC Method
    def get_gbp_details(self, context, **kwargs):
        port_id = self._core_plugin._device_to_port_id(
            kwargs['device'])
        port_context = self._core_plugin.get_bound_port_context(
            context, port_id, kwargs['host'])
        if not port_context:
            LOG.warning(_("Device %(device)s requested by agent "
                          "%(agent_id)s not found in database"),
                        {'device': port_id,
                         'agent_id': kwargs.get('agent_id')})
            return
        port = port_context.current

        # retrieve PTG from a given Port
        ptg = self._port_id_to_ptg(context, port['id'])
        l2p = self._network_id_to_l2p(context, port['network_id'])
        if not ptg and not l2p:
            return
        context._plugin = self.gbp_plugin
        context._plugin_context = context

        l2_policy_id = l2p['id']
        ptg_tenant = self._tenant_by_sharing_policy(ptg or l2p)
        if ptg:
            endpoint_group_name = self.name_mapper.policy_target_group(
                context, ptg['id'])
        else:
            endpoint_group_name = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=SHADOW_PREFIX)

        def is_port_promiscuous(port):
            return (port['device_owner'] in PROMISCUOUS_TYPES or
                    port['name'].endswith(PROMISCUOUS_SUFFIX))

        details = {'device': kwargs.get('device'),
                   'port_id': port_id,
                   'mac_address': port['mac_address'],
                   'app_profile_name': str(
                       self.apic_manager.app_profile_name),
                   'l2_policy_id': l2_policy_id,
                   'tenant_id': port['tenant_id'],
                   'host': port[portbindings.HOST_ID],
                   'ptg_tenant': self.apic_manager.apic.fvTenant.name(
                       ptg_tenant),
                   'endpoint_group_name': str(endpoint_group_name),
                   'promiscuous_mode': is_port_promiscuous(port)}
        if port['device_owner'].startswith('compute:') and port['device_id']:
            vm = nclient.NovaClient().get_server(port['device_id'])
            details['vm-name'] = vm.name if vm else port['device_id']
        return details

    def process_port_added(self, plugin_context, port):
        pass

    def create_policy_action_precommit(self, context):
        pass

    def create_policy_rule_precommit(self, context):
        if ('policy_actions' in context.current and
                len(context.current['policy_actions']) != 1):
            # TODO(ivar): to be fixed when redirect is supported
            raise ExactlyOneActionPerRuleIsSupportedOnApicDriver()

    def create_policy_rule_postcommit(self, context, transaction=None):
        action = context._plugin.get_policy_action(
            context._plugin_context, context.current['policy_actions'][0])
        classifier = context._plugin.get_policy_classifier(
            context._plugin_context,
            context.current['policy_classifier_id'])
        if action['action_type'] in ALLOWING_ACTIONS:
            port_min, port_max = (
                gpdb.GroupPolicyMappingDbPlugin._get_min_max_ports_from_range(
                    classifier['port_range']))
            attrs = {'etherT': 'unspecified'}
            if classifier['protocol']:
                attrs['etherT'] = 'ip'
                attrs['prot'] = classifier['protocol'].lower()
                if port_min and port_max:
                    attrs['dToPort'] = port_max
                    attrs['dFromPort'] = port_min
            tenant = self._tenant_by_sharing_policy(context.current)
            policy_rule = self.name_mapper.policy_rule(context,
                                                       context.current['id'])
            with self.apic_manager.apic.transaction(transaction) as trs:
                self.apic_manager.create_tenant_filter(
                    policy_rule, owner=tenant, transaction=trs, **attrs)
                # Also create reverse rule
                if attrs.get('prot') in REVERTIBLE_PROTOCOLS:
                    if attrs['prot'] == n_constants.PROTO_NAME_TCP.lower():
                        policy_rule = self.name_mapper.policy_rule(
                            context, context.current['id'],
                            prefix=REVERSE_PREFIX)
                        if attrs.get('dToPort') and attrs.get('dFromPort'):
                            attrs.pop('dToPort')
                            attrs.pop('dFromPort')
                            attrs['sToPort'] = port_max
                            attrs['sFromPort'] = port_min
                        attrs['tcpRules'] = 'est'
                        self.apic_manager.create_tenant_filter(
                            policy_rule, owner=tenant, transaction=trs,
                            **attrs)

    def create_policy_rule_set_precommit(self, context):
        if context.current['child_policy_rule_sets']:
            raise HierarchicalContractsNotSupported()

    def create_policy_rule_set_postcommit(self, context):
        # Create APIC policy_rule_set
        tenant = self._tenant_by_sharing_policy(context.current)
        contract = self.name_mapper.policy_rule_set(context,
                                                    context.current['id'])
        with self.apic_manager.apic.transaction(None) as trs:
            self.apic_manager.create_contract(
                contract, owner=tenant, transaction=trs)
            rules = self.gbp_plugin.get_policy_rules(
                context._plugin_context,
                {'id': context.current['policy_rules']})
            self._apply_policy_rule_set_rules(
                context, context.current, rules, transaction=trs)

    def create_policy_target_postcommit(self, context):
        if not context.current['port_id']:
            self._use_implicit_port(context)
        port = self._core_plugin.get_port(context._plugin_context,
                                          context.current['port_id'])
        if self._is_port_bound(port):
            self._notify_port_update(context._plugin_context, port['id'])

    def create_policy_target_group_precommit(self, context):
        if context.current['subnets']:
            raise ExplicitSubnetAssociationNotSupported()

    def create_policy_target_group_postcommit(self, context):
        if not context.current['subnets']:
            self._use_implicit_subnet(context)
        tenant = self._tenant_by_sharing_policy(context.current)
        l2_policy = self.name_mapper.l2_policy(context,
                                               context.current['l2_policy_id'])
        epg = self.name_mapper.policy_target_group(context,
                                                   context.current['id'])
        l2_policy_object = context._plugin.get_l2_policy(
            context._plugin_context, context.current['l2_policy_id'])
        bd_owner = self._tenant_by_sharing_policy(l2_policy_object)
        with self.apic_manager.apic.transaction(None) as trs:
            self.apic_manager.ensure_epg_created(tenant, epg,
                                                 bd_owner=bd_owner,
                                                 bd_name=l2_policy)

            l2p = context._plugin.get_l2_policy(
                context._plugin_context, context.current['l2_policy_id'])
            self._configure_epg_service_contract(
                context, context.current, l2p, epg, transaction=trs)
            self._configure_epg_implicit_contract(
                context, context.current, l2p, epg, transaction=trs)

        self._manage_ptg_policy_rule_sets(
                context, context.current['provided_policy_rule_sets'],
                context.current['consumed_policy_rule_sets'], [], [])

    def create_l2_policy_precommit(self, context):
        self._reject_non_shared_net_on_shared_l2p(context)

    def update_l2_policy_precommit(self, context):
        self._reject_non_shared_net_on_shared_l2p(context)
        self._reject_shared_update(context, 'l2_policy')

    def create_l2_policy_postcommit(self, context):
        super(ApicMappingDriver, self).create_l2_policy_postcommit(context)
        tenant = self._tenant_by_sharing_policy(context.current)
        l3_policy = self.name_mapper.l3_policy(context,
                                               context.current['l3_policy_id'])
        l2_policy = self.name_mapper.l2_policy(context, context.current['id'])
        l3_policy_object = context._plugin.get_l3_policy(
            context._plugin_context, context.current['l3_policy_id'])
        ctx_owner = self._tenant_by_sharing_policy(l3_policy_object)
        with self.apic_manager.apic.transaction(None) as trs:
            self.apic_manager.ensure_bd_created_on_apic(
                tenant, l2_policy, ctx_owner=ctx_owner, ctx_name=l3_policy,
                transaction=trs)
            # Create neutron port EPG
            self._configure_shadow_epg(context, context.current, l2_policy,
                                       transaction=trs)
            self._configure_implicit_contract(context, context.current,
                                              transaction=trs)
            # Add existing subnets
            net_id = context.current['network_id']
            subnets = self._core_plugin.get_subnets(context._plugin_context,
                                                    {'network_id': [net_id]})
            self._manage_l2p_subnets(
                context._plugin_context, context.current['id'], subnets, [],
                transaction=trs)

    def update_l2_policy_postcommit(self, context):
        pass

    def create_l3_policy_precommit(self, context):
        self._check_l3p_es(context)

    def create_l3_policy_postcommit(self, context):
        tenant = self._tenant_by_sharing_policy(context.current)
        l3_policy = self.name_mapper.l3_policy(context, context.current['id'])
        self.apic_manager.ensure_context_enforced(tenant, l3_policy)
        external_segments = context.current['external_segments']
        if external_segments:
            # Create a L3 ext for each External Segment
            ess = context._plugin.get_external_segments(
                context._plugin_context,
                filters={'id': external_segments.keys()})
            for es in ess:
                self._plug_l3p_to_es(context, es)

    def delete_policy_rule_postcommit(self, context):
        for prs in context._plugin.get_policy_rule_sets(
                context._plugin_context,
                filters={'id': context.current['policy_rule_sets']}):
            self._remove_policy_rule_set_rules(context, prs, [context.current])
        self._delete_policy_rule_from_apic(context)

    def _delete_policy_rule_from_apic(self, context, transaction=None):
        tenant = self._tenant_by_sharing_policy(context.current)
        policy_rule = self.name_mapper.policy_rule(context,
                                                   context.current['id'])
        with self.apic_manager.apic.transaction(transaction) as trs:
            self.apic_manager.delete_tenant_filter(policy_rule, owner=tenant,
                                                   transaction=trs)
            # Delete policy reverse rule
            policy_rule = self.name_mapper.policy_rule(
                context, context.current['id'], prefix=REVERSE_PREFIX)
            self.apic_manager.delete_tenant_filter(policy_rule, owner=tenant,
                                                   transaction=trs)

    def delete_policy_rule_set_precommit(self, context):
        # Intercept Parent Call
        pass

    def delete_policy_rule_set_postcommit(self, context):
        tenant = self._tenant_by_sharing_policy(context.current)
        contract = self.name_mapper.policy_rule_set(context,
                                                    context.current['id'])
        self.apic_manager.delete_contract(contract, owner=tenant)

    def delete_policy_target_postcommit(self, context):
        try:
            if context.current['port_id']:
                port = self._core_plugin.get_port(context._plugin_context,
                                                  context.current['port_id'])
                # Delete Neutron's port
                port_id = context.current['port_id']
                self._cleanup_port(context._plugin_context, port_id)
                # Notify the agent. If the port has been deleted by the
                # parent method the notification will not be done
                self._notify_port_update(context._plugin_context, port['id'])
        except n_exc.PortNotFound:
            LOG.warn(_("Port %s is missing") % context.current['port_id'])
            return

    def delete_policy_target_group_precommit(self, context):
        pass

    def delete_policy_target_group_postcommit(self, context):
        tenant = self._tenant_by_sharing_policy(context.current)
        ptg = self.name_mapper.policy_target_group(context,
                                                   context.current['id'])

        self.apic_manager.delete_epg_for_network(tenant, ptg)

    def delete_l2_policy_postcommit(self, context):
        super(ApicMappingDriver, self).delete_l2_policy_postcommit(context)
        tenant = self._tenant_by_sharing_policy(context.current)
        l2_policy = self.name_mapper.l2_policy(context, context.current['id'])

        with self.apic_manager.apic.transaction(None) as trs:
            self.apic_manager.delete_bd_on_apic(
                tenant, l2_policy, transaction=trs)
            # Delete neutron port EPG
            self._delete_shadow_epg(context, context.current, transaction=trs)
            self._delete_implicit_contract(context, context.current,
                                           transaction=trs)

    def delete_l3_policy_postcommit(self, context):
        tenant = self._tenant_by_sharing_policy(context.current)
        l3_policy = self.name_mapper.l3_policy(context, context.current['id'])

        self.apic_manager.ensure_context_deleted(tenant, l3_policy)
        external_segments = context.current['external_segments']
        if external_segments:
            # Create a L3 ext for each External Segment
            ess = context._plugin.get_external_segments(
                context._plugin_context,
                filters={'id': external_segments.keys()})
            for es in ess:
                self._unplug_l3p_from_es(context, es)

    def update_policy_rule_set_precommit(self, context):
        self._reject_shared_update(context, 'policy_rule_set')
        self._reject_multiple_redirects_in_prs(context)
        if context.current['child_policy_rule_sets']:
            raise HierarchicalContractsNotSupported()
        # If a redirect action is added (from 0 to one) we have to validate
        # the providing and consuming PTGs
        old_red_count = self._multiple_pr_redirect_action_number(
            context._plugin_context.session, context.original['policy_rules'])
        new_red_count = self._multiple_pr_redirect_action_number(
            context._plugin_context.session, context.current['policy_rules'])
        if new_red_count > old_red_count:
            self._validate_new_prs_redirect(context, context.current)

    def update_policy_rule_set_postcommit(self, context):
        # Update policy_rule_set rules
        old_rules = set(context.original['policy_rules'])
        new_rules = set(context.current['policy_rules'])
        to_add = context._plugin.get_policy_rules(
            context._plugin_context, {'id': new_rules - old_rules})
        to_remove = context._plugin.get_policy_rules(
            context._plugin_context, {'id': old_rules - new_rules})
        self._remove_policy_rule_set_rules(context, context.current, to_remove)
        self._apply_policy_rule_set_rules(context, context.current, to_add)

    def update_policy_target_precommit(self, context):
        if (context.original['policy_target_group_id'] !=
                context.current['policy_target_group_id']):
            if context.current['policy_target_group_id']:
                self._validate_pt_port_subnets(context)

    def update_policy_target_postcommit(self, context):
        if (context.original['policy_target_group_id'] !=
                context.current['policy_target_group_id']):
            self._notify_port_update(context._plugin_context,
                                     context.current['port_id'])

    def update_policy_rule_precommit(self, context):
        self._reject_multiple_redirects_in_rule(context)
        old_redirect = self._get_redirect_action(context, context.original)
        new_redirect = self._get_redirect_action(context, context.current)
        if not old_redirect and new_redirect:
            # If redirect action is added, check that there's no contract that
            # already has a redirect action
            for prs in context._plugin.get_policy_rule_sets(
                    context._plugin_context,
                    {'id': context.current['policy_rule_sets']}):
                # Make sure the PRS can have a new redirect action
                self._validate_new_prs_redirect(context, prs)

    def update_policy_rule_postcommit(self, context):
        self._update_policy_rule_on_apic(context)

    def update_policy_action_postcommit(self, context):
        pass

    def _update_policy_rule_on_apic(self, context):
        self._delete_policy_rule_from_apic(context, transaction=None)
        # The following only creates the APIC reference
        self.create_policy_rule_postcommit(context, transaction=None)

    def update_policy_target_group_precommit(self, context):
        if set(context.original['subnets']) != set(context.current['subnets']):
            raise ExplicitSubnetAssociationNotSupported()
        self._reject_shared_update(context, 'policy_target_group')

    def update_policy_target_group_postcommit(self, context):
        # TODO(ivar): refactor parent to avoid code duplication
        orig_provided_policy_rule_sets = context.original[
            'provided_policy_rule_sets']
        curr_provided_policy_rule_sets = context.current[
            'provided_policy_rule_sets']
        orig_consumed_policy_rule_sets = context.original[
            'consumed_policy_rule_sets']
        curr_consumed_policy_rule_sets = context.current[
            'consumed_policy_rule_sets']

        new_provided_policy_rule_sets = list(
            set(curr_provided_policy_rule_sets) - set(
                orig_provided_policy_rule_sets))
        new_consumed_policy_rule_sets = list(
            set(curr_consumed_policy_rule_sets) - set(
                orig_consumed_policy_rule_sets))
        removed_provided_policy_rule_sets = list(
            set(orig_provided_policy_rule_sets) - set(
                curr_provided_policy_rule_sets))
        removed_consumed_policy_rule_sets = list(
            set(orig_consumed_policy_rule_sets) - set(
                curr_consumed_policy_rule_sets))

        self._manage_ptg_policy_rule_sets(
            context, new_provided_policy_rule_sets,
            new_consumed_policy_rule_sets, removed_provided_policy_rule_sets,
            removed_consumed_policy_rule_sets)

    def update_l3_policy_precommit(self, context):
        self._reject_shared_update(context, 'l3_policy')
        self._check_l3p_es(context)

    def update_l3_policy_postcommit(self, context):
        old_segment_dict = context.original['external_segments']
        new_segment_dict = context.current['external_segments']
        if (context.current['external_segments'] !=
                context.original['external_segments']):
            new_segments = set(new_segment_dict.keys())
            old_segments = set(old_segment_dict.keys())
            added = new_segments - old_segments
            removed = old_segments - new_segments
            # Modified ES are treated like new ones
            modified = set(x for x in (new_segments - added) if
                        (set(old_segment_dict[x]) != set(new_segment_dict[x])))
            added |= modified
            # The following operations could be intra-tenant, can't be executed
            # in a single transaction
            if added:
                # Create a L3 ext for each External Segment
                added_ess = context._plugin.get_external_segments(
                    context._plugin_context, filters={'id': added})
                for es in added_ess:
                    self._plug_l3p_to_es(context, es)
            if removed:
                removed_ess = context._plugin.get_external_segments(
                    context._plugin_context, filters={'id': removed})
                for es in removed_ess:
                    self._unplug_l3p_from_es(context, es)

    def create_policy_classifier_precommit(self, context):
        pass

    def create_policy_classifier_postcommit(self, context):
        pass

    def update_policy_classifier_precommit(self, context):
        pass

    def update_policy_classifier_postcommit(self, context):
        admin_context = nctx.get_admin_context()
        if not context.current['policy_rules']:
            return
        rules = context._plugin.get_policy_rules(
                admin_context,
                filters={'id': context.current['policy_rules']})
        # Rewrite the rule on the APIC
        for rule in rules:
            rule_context = group_policy_context.PolicyRuleContext(
                context._plugin, context._plugin_context, rule)
            self._update_policy_rule_on_apic(rule_context)
            # If direction or protocol changed, the contracts should be updated
            o_dir = context.original['direction']
            c_dir = context.current['direction']
            o_prot = context.original['protocol']
            c_prot = context.current['protocol']
            # TODO(ivar): Optimize by aggregating on PRS ID
            if ((o_dir != c_dir) or
                    ((o_prot in REVERTIBLE_PROTOCOLS) !=
                        (c_prot in REVERTIBLE_PROTOCOLS))):
                for prs in context._plugin.get_policy_rule_sets(
                        admin_context,
                        filters={'id': rule['policy_rule_sets']}):
                    self._remove_policy_rule_set_rules(
                        context, prs, [(rule, context.original)])
                    self._apply_policy_rule_set_rules(context, prs, [rule])

    def create_external_segment_precommit(self, context):
        if context.current['port_address_translation']:
            raise PATNotSupportedByApicDriver()
        ext_info = self.apic_manager.ext_net_dict.get(
            context.current['name'])
        if ext_info and ext_info.get('cidr_exposed'):
            db_es = context._plugin._get_external_segment(
                context._plugin_context, context.current['id'])
            net = netaddr.IPNetwork(ext_info.get('cidr_exposed'))
            db_es.cidr = str(net)
            db_es.ip_version = net[0].version
            context.current['cidr'] = db_es.cidr
            context.current['ip_version'] = db_es.ip_version
        else:
            LOG.warn(UNMANAGED_SEGMENT % context.current['id'])

    def create_external_segment_postcommit(self, context):
        external_info = self.apic_manager.ext_net_dict.get(
            context.current['name'])
        if not external_info:
            LOG.warn(UNMANAGED_SEGMENT % context.current['id'])

    def update_external_segment_precommit(self, context):
        if context.current['port_address_translation']:
            raise PATNotSupportedByApicDriver()

    def update_external_segment_postcommit(self, context):
        ext_info = self.apic_manager.ext_net_dict.get(
            context.current['name'])
        if not ext_info:
            LOG.warn(UNMANAGED_SEGMENT % context.current['id'])
            return
        if (context.current['external_routes'] !=
                context.original['external_routes']):
            new_routes_dict = self._build_routes_dict(
                context.current['external_routes'])
            new_routes = set((x['destination'], x['nexthop'])
                             for x in context.current['external_routes'])
            old_routes = set((x['destination'], x['nexthop'])
                             for x in context.original['external_routes'])
            added = new_routes - old_routes
            removed = old_routes - new_routes
            switch = ext_info['switch']
            default_gateway = ext_info['gateway_ip']
            es_name = self.name_mapper.external_segment(
                context, context.current['id'])
            es_tenant = self._tenant_by_sharing_policy(context.current)
            ep_names = [self.name_mapper.external_policy(context, x)
                        for x in context.current['external_policies']]

            nexthop = lambda h: h if h else default_gateway
            with self.apic_manager.apic.transaction() as trs:
                for route in removed:
                    if route[0] not in new_routes_dict:
                        # Remove Route completely
                        self.apic_manager.ensure_static_route_deleted(
                            es_name, switch, route[0], owner=es_tenant,
                            transaction=trs)
                        # Also from External EPG
                        del_epg = (self.apic_manager.
                                   ensure_external_epg_routes_deleted)
                        for ep in ep_names:
                            del_epg(
                                es_name, external_epg=ep, owner=es_tenant,
                                subnets=[route[0]], transaction=trs)
                    else:
                        # Only remove nexthop
                        self.apic_manager.ensure_next_hop_deleted(
                            es_name, switch, route[0], nexthop(route[1]),
                            owner=es_tenant, transaction=trs)
                for route in added:
                    # Create Static Route on External Routed Network
                    self.apic_manager.ensure_static_route_created(
                        es_name, switch, nexthop(route[1]),
                        owner=es_tenant, subnet=route[0], transaction=trs)
                    # And on the External EPGs
                    for ep in ep_names:
                        self.apic_manager.ensure_external_epg_created(
                            es_name, subnet=route[0], external_epg=ep,
                            owner=es_tenant, transaction=trs)

    def delete_external_segment_precommit(self, context):
        pass

    def delete_external_segment_postcommit(self, context):
        # If not in use, there's no representation of it in the APIC
        pass

    def create_external_policy_precommit(self, context):
        pass

    def create_external_policy_postcommit(self, context):
        segments = context.current['external_segments']
        provided_prs = context.current['provided_policy_rule_sets']
        consumed_prs = context.current['consumed_policy_rule_sets']
        self._plug_externa_policy_to_segment(
            context, context.current, segments, provided_prs, consumed_prs)

    def update_external_policy_precommit(self, context):
        pass

    def update_external_policy_postcommit(self, context):
        added_segments = (set(context.current['external_segments']) -
                          set(context.original['external_segments']))
        removed_segments = (set(context.original['external_segments']) -
                            set(context.current['external_segments']))
        # Remove segments
        self._unplug_external_policy_from_segment(
            context, context.current, removed_segments)
        # Add new segments
        provided_prs = context.current['provided_policy_rule_sets']
        consumed_prs = context.current['consumed_policy_rule_sets']
        self._plug_externa_policy_to_segment(
            context, context.current, added_segments, provided_prs,
            consumed_prs)
        # Manage updated PRSs
        added_p_prs = (set(context.current['provided_policy_rule_sets']) -
                       set(context.original['provided_policy_rule_sets']))
        removed_p_prs = (set(context.original['provided_policy_rule_sets']) -
                         set(context.current['provided_policy_rule_sets']))
        added_c_prs = (set(context.current['consumed_policy_rule_sets']) -
                       set(context.original['consumed_policy_rule_sets']))
        removed_c_prs = (set(context.original['consumed_policy_rule_sets']) -
                         set(context.current['consumed_policy_rule_sets']))
        # Avoid duplicating requests
        delta_segments = [x for x in context.current['external_segments']
                          if x not in added_segments]
        new_ess = context._plugin.get_external_segments(
            context._plugin_context,
            filters={'id': delta_segments})
        for es in new_ess:
            if es['name'] in self.apic_manager.ext_net_dict:
                self._manage_ep_policy_rule_sets(
                    context._plugin_context, es, context.current, added_p_prs,
                    added_c_prs, removed_p_prs, removed_c_prs)

    def delete_external_policy_precommit(self, context):
        pass

    def delete_external_policy_postcommit(self, context):
        external_segments = context.current['external_segments']
        self._unplug_external_policy_from_segment(
            context, context.current, external_segments)

    def process_subnet_changed(self, context, old, new):
        if old['gateway_ip'] != new['gateway_ip']:
            l2p = self._network_id_to_l2p(context, new['network_id'])
            if l2p:
                # Is GBP owned, reflect on APIC
                self._manage_l2p_subnets(context, l2p['id'], [new], [old])

    def process_subnet_added(self, context, subnet):
        l2p = self._network_id_to_l2p(context, subnet['network_id'])
        if l2p:
            self._sync_epg_subnets(context, l2p)
            self._manage_l2p_subnets(context, l2p['id'], [subnet], [])

    def process_subnet_deleted(self, context, subnet):
        l2p = self._network_id_to_l2p(context, subnet['network_id'])
        if l2p:
            self._manage_l2p_subnets(context, l2p['id'], [], [subnet])

    def process_port_changed(self, context, old, new):
        pass

    def process_pre_port_deleted(self, context, port):
        pt = self._port_id_to_pt(context, port['id'])
        if pt:
            context.policy_target_id = pt['id']

    def process_port_deleted(self, context, port):
        try:
            self.gbp_plugin.delete_policy_target(
                context, context.policy_target_id)
        except AttributeError:
            pass

    def _apply_policy_rule_set_rules(
            self, context, policy_rule_set, policy_rules, transaction=None):
        # TODO(ivar): parent contract filtering when supported
        self._manage_policy_rule_set_rules(
            context, policy_rule_set, policy_rules, transaction=transaction)

    def _remove_policy_rule_set_rules(
            self, context, policy_rule_set, policy_rules, transaction=None):
        self._manage_policy_rule_set_rules(
            context, policy_rule_set, policy_rules, unset=True,
            transaction=transaction)

    def _manage_policy_rule_set_rules(
            self, context, policy_rule_set, policy_rules, unset=False,
            transaction=None, classifier=None):
        # REVISIT(ivar): figure out what should be moved in apicapi instead
        if policy_rules:
            tenant = self._tenant_by_sharing_policy(policy_rule_set)
            contract = self.name_mapper.policy_rule_set(
                context, policy_rule_set['id'])
            in_dir = [g_const.GP_DIRECTION_BI, g_const.GP_DIRECTION_IN]
            out_dir = [g_const.GP_DIRECTION_BI, g_const.GP_DIRECTION_OUT]
            for rule in policy_rules:
                if isinstance(rule, tuple):
                    classifier = rule[1]
                    rule = rule[0]
                else:
                    classifier = context._plugin.get_policy_classifier(
                            context._plugin_context,
                            rule['policy_classifier_id'])
                policy_rule = self.name_mapper.policy_rule(context, rule['id'])
                reverse_policy_rule = self.name_mapper.policy_rule(
                    context, rule['id'], prefix=REVERSE_PREFIX)
                rule_owner = self._tenant_by_sharing_policy(rule)
                with self.apic_manager.apic.transaction(transaction) as trs:
                    if classifier['direction'] in in_dir:
                        # PRS and subject are the same thing in this case
                        self.apic_manager.manage_contract_subject_in_filter(
                            contract, contract, policy_rule, owner=tenant,
                            transaction=trs, unset=unset,
                            rule_owner=rule_owner)
                        if (classifier['protocol'].lower() in
                                REVERTIBLE_PROTOCOLS):
                            (self.apic_manager.
                             manage_contract_subject_out_filter(
                                 contract, contract, reverse_policy_rule,
                                 owner=tenant, transaction=trs, unset=unset,
                                 rule_owner=rule_owner))
                    if classifier['direction'] in out_dir:
                        # PRS and subject are the same thing in this case
                        self.apic_manager.manage_contract_subject_out_filter(
                            contract, contract, policy_rule, owner=tenant,
                            transaction=trs, unset=unset,
                            rule_owner=rule_owner)
                        if (classifier['protocol'].lower() in
                                REVERTIBLE_PROTOCOLS):
                            (self.apic_manager.
                             manage_contract_subject_in_filter(
                                 contract, contract, reverse_policy_rule,
                                 owner=tenant, transaction=trs, unset=unset,
                                 rule_owner=rule_owner))

    def _manage_ptg_policy_rule_sets(
            self, ptg_context, added_provided, added_consumed,
            removed_provided, removed_consumed, transaction=None):
        context = ptg_context
        plugin_context = context._plugin_context
        ptg = context.current
        ptg_params = []

        # TODO(ivar): change APICAPI to not expect a resource context
        plugin_context._plugin = self.gbp_plugin
        plugin_context._plugin_context = plugin_context
        mapped_tenant = self._tenant_by_sharing_policy(ptg)
        mapped_ptg = self.name_mapper.policy_target_group(
            plugin_context, ptg['id'])
        ptg_params.append((mapped_tenant, mapped_ptg))
        provided = [added_provided, removed_provided]
        consumed = [added_consumed, removed_consumed]
        methods = [self.apic_manager.set_contract_for_epg,
                   self.apic_manager.unset_contract_for_epg]

        for x in xrange(len(provided)):
            for c in self.gbp_plugin.get_policy_rule_sets(
                    plugin_context, filters={'id': provided[x]}):
                c_owner = self._tenant_by_sharing_policy(c)
                c = self.name_mapper.policy_rule_set(plugin_context,
                                                     c['id'])
                for params in ptg_params:
                    methods[x](params[0], params[1], c, provider=True,
                               contract_owner=c_owner, transaction=None)
        for x in xrange(len(consumed)):
            for c in self.gbp_plugin.get_policy_rule_sets(
                    plugin_context, filters={'id': consumed[x]}):
                c_owner = self._tenant_by_sharing_policy(c)
                c = self.name_mapper.policy_rule_set(plugin_context,
                                                     c['id'])
                for params in ptg_params:
                    methods[x](params[0], params[1], c, provider=False,
                               contract_owner=c_owner, transaction=None)

    def _manage_ep_policy_rule_sets(
            self, plugin_context, es, ep, added_provided, added_consumed,
            removed_provided, removed_consumed, transaction=None):

        ext_info = self.apic_manager.ext_net_dict.get(es['name'])
        if not ext_info:
            LOG.warn(_("External Segment %s is not managed by APIC "
                     "mapping driver.") % es['id'])
            return
        plugin_context._plugin = self.gbp_plugin
        plugin_context._plugin_context = plugin_context
        mapped_tenant = self._tenant_by_sharing_policy(es)
        mapped_es = self.name_mapper.external_segment(plugin_context, es['id'])

        mapped_ep = self.name_mapper.external_policy(plugin_context,
                                                     ep['id'])
        provided = [added_provided, removed_provided]
        consumed = [added_consumed, removed_consumed]
        methods = [self.apic_manager.set_contract_for_external_epg,
                   self.apic_manager.unset_contract_for_external_epg]
        with self.apic_manager.apic.transaction(transaction) as trs:
            for x in xrange(len(provided)):
                for c in provided[x]:
                    c = self.name_mapper.policy_rule_set(plugin_context, c)
                    methods[x](mapped_es, c, external_epg=mapped_ep,
                               owner=mapped_tenant, provided=True,
                               transaction=trs)
            for x in xrange(len(consumed)):
                for c in consumed[x]:
                    c = self.name_mapper.policy_rule_set(plugin_context, c)
                    methods[x](mapped_es, c, external_epg=mapped_ep,
                               owner=mapped_tenant, provided=False,
                               transaction=trs)

    def _manage_l2p_subnets(self, plugin_context, l2p_id, added_subnets,
                            removed_subnets, transaction=None):
        # TODO(ivar): change APICAPI to not expect a resource context
        plugin_context._plugin = self.gbp_plugin
        plugin_context._plugin_context = plugin_context
        l2_policy_object = self.gbp_plugin.get_l2_policy(
            plugin_context, l2p_id)
        mapped_tenant = self._tenant_by_sharing_policy(l2_policy_object)
        mapped_l2p = self.name_mapper.l2_policy(plugin_context, l2p_id)
        subnets = [added_subnets, removed_subnets]
        methods = [self.apic_manager.ensure_subnet_created_on_apic,
                   self.apic_manager.ensure_subnet_deleted_on_apic]
        with self.apic_manager.apic.transaction(transaction) as trs:
            for x in xrange(len(subnets)):
                for s in subnets[x]:
                    methods[x](mapped_tenant, mapped_l2p, self._gateway_ip(s),
                               transaction=trs)

    def _update_default_security_group(self, plugin_context, ptg_id,
                                       tenant_id, subnets=None):
        pass

    def _assoc_ptg_sg_to_pt(self, context, pt_id, ptg_id):
        pass

    def _handle_policy_rule_sets(self, context):
        pass

    def _gateway_ip(self, subnet):
        cidr = netaddr.IPNetwork(subnet['cidr'])
        return '%s/%s' % (subnet['gateway_ip'], str(cidr.prefixlen))

    def _subnet_ids_to_objects(self, plugin_context, ids):
        return self._core_plugin.get_subnets(plugin_context,
                                             filters={'id': ids})

    def _port_to_ptg_network(self, context, port_id):
        ptg = self._port_id_to_ptg(context, port_id)
        if not ptg:
            # Not GBP port
            return None, None
        network = self._l2p_id_to_network(context, ptg['l2_policy_id'])
        return ptg, network

    def _port_id_to_pt(self, context, port_id):
        pt = (context.session.query(gpdb.PolicyTargetMapping).
              filter_by(port_id=port_id).first())
        if pt:
            db_utils = gpdb.GroupPolicyMappingDbPlugin()
            return db_utils._make_policy_target_dict(pt)

    def _port_id_to_ptg(self, context, port_id):
        pt = self._port_id_to_pt(context, port_id)
        if pt:
            return self.gbp_plugin.get_policy_target_group(
                context, pt['policy_target_group_id'])
        return

    def _l2p_id_to_network(self, context, l2p_id):
        l2_policy = self.gbp_plugin.get_l2_policy(context, l2p_id)
        return self._core_plugin.get_network(context, l2_policy['network_id'])

    def _network_id_to_l2p(self, context, network_id):
        l2ps = self.gbp_plugin.get_l2_policies(
            context, filters={'network_id': [network_id]})
        for l2p in l2ps:
            if l2p['network_id'] == network_id:
                return l2p

    def _subnet_to_ptg(self, context, subnet_id):
        ptg = (context.session.query(gpdb.PolicyTargetGroupMapping).
               join(gpdb.PolicyTargetGroupMapping.subnets).
               filter(gpdb.PTGToSubnetAssociation.subnet_id ==
                      subnet_id).
               first())
        if ptg:
            db_utils = gpdb.GroupPolicyMappingDbPlugin()
            return db_utils._make_policy_target_group_dict(ptg)

    def _plug_l3p_to_es(self, context, external_segment):
        l3_policy = self.name_mapper.l3_policy(context, context.current['id'])
        es = external_segment
        external_segments = context.current['external_segments']
        ext_info = self.apic_manager.ext_net_dict.get(es['name'])
        if not ext_info:
            LOG.warn(UNMANAGED_SEGMENT % es['id'])
            return
        ip = external_segments[es['id']]
        if ip and ip[0]:
            ip = ip[0]
            exposed = ip + '/' + es['cidr'].split('/')[1]
        else:
            ip = ext_info.get('cidr_exposed', '/').split('/')[0]
            exposed = ext_info.get('cidr_exposed')

        if not ip:
            raise NoAddressConfiguredOnExternalSegment(
                l3p_id=context.current['id'], es_id=es['id'])
        context.set_external_fixed_ips(es['id'], [ip])
        encap = ext_info.get('encap')  # No encap if None
        switch = ext_info['switch']
        module, sport = ext_info['port'].split('/')
        router_id = ext_info['router_id']
        default_gateway = ext_info['gateway_ip']
        es_name = self.name_mapper.external_segment(
            context, es['id'])
        es_tenant = self._tenant_by_sharing_policy(es)
        with self.apic_manager.apic.transaction() as trs:
            # Create External Routed Network connected to the proper
            # L3 Context
            self.apic_manager.ensure_external_routed_network_created(
                es_name, owner=es_tenant, context=l3_policy,
                transaction=trs)
            self.apic_manager.ensure_logical_node_profile_created(
                es_name, switch, module, sport, encap,
                exposed, owner=es_tenant,
                router_id=router_id, transaction=trs)
            for route in es['external_routes']:
                self.apic_manager.ensure_static_route_created(
                    es_name, switch, route['nexthop'] or default_gateway,
                    owner=es_tenant,
                    subnet=route['destination'], transaction=trs)

    def _unplug_l3p_from_es(self, context, es):
        es_name = self.name_mapper.external_segment(context, es['id'])
        es_tenant = self._tenant_by_sharing_policy(es)
        self.apic_manager.delete_external_routed_network(
            es_name, owner=es_tenant)

    def _build_routes_dict(self, routes):
        result = {}
        for route in routes:
            if route['destination'] not in result:
                result[route['destination']] = []
            result[route['destination']].append(route['nexthop'])
        return result

    def _plug_externa_policy_to_segment(self, context, ep, segments,
                                        provided_prs, consumed_prs):
        if segments:
            added_ess = context._plugin.get_external_segments(
                context._plugin_context, filters={'id': segments})
            ep_name = self.name_mapper.external_policy(
                context, ep['id'])
            for es in added_ess:
                ext_info = self.apic_manager.ext_net_dict.get(es['name'])
                if not ext_info:
                    LOG.warn(UNMANAGED_SEGMENT % es['id'])
                    continue
                es_name = self.name_mapper.external_segment(context, es['id'])
                es_tenant = self._tenant_by_sharing_policy(es)
                with self.apic_manager.apic.transaction() as trs:
                    # Create External EPG
                    subnets = set(x['destination'] for
                                  x in es['external_routes'])
                    for s in subnets:
                        self.apic_manager.ensure_external_epg_created(
                            es_name, subnet=s, external_epg=ep_name,
                            owner=es_tenant, transaction=trs)
                    # Provide and consume contracts
                    self._manage_ep_policy_rule_sets(
                        context._plugin_context, es, ep,
                        provided_prs, consumed_prs, [], [], transaction=trs)

    def _unplug_external_policy_from_segment(self, context, ep, segments):
        if segments:
            added_ess = context._plugin.get_external_segments(
                context._plugin_context, filters={'id': segments})
            ep_name = self.name_mapper.external_policy(
                context, ep['id'])
            for es in added_ess:
                ext_info = self.apic_manager.ext_net_dict.get(es['name'])
                if not ext_info:
                    LOG.warn(UNMANAGED_SEGMENT % es['id'])
                    continue
                es_name = self.name_mapper.external_segment(context, es['id'])
                es_tenant = self._tenant_by_sharing_policy(es)
                self.apic_manager.ensure_external_epg_deleted(
                        es_name, external_epg=ep_name, owner=es_tenant)

    def _check_l3p_es(self, context):
        l3p = context.current
        if l3p['external_segments']:
            # Check not used
            ess = context._plugin.get_external_segments(
                context._plugin_context,
                filters={'id': l3p['external_segments'].keys()})
            for es in ess:
                if [x for x in es['l3_policies'] if x != l3p['id']]:
                    raise OnlyOneL3PolicyIsAllowedPerExternalSegment()
            for allocations in l3p['external_segments'].values():
                if len(allocations) > 1:
                    raise OnlyOneAddressIsAllowedPerExternalSegment()

    def _get_ptg_by_subnet(self, plugin_context, subnet_id):
        ptgass = (plugin_context.session.query(gpdb.PTGToSubnetAssociation).
                  filter_by(subnet_id=subnet_id).first())
        if ptgass:
            return self.gbp_plugin.get_policy_target_group(
                plugin_context, ptgass['policy_target_group_id'])

    def _reject_shared_update(self, context, type):
        if context.original.get('shared') != context.current.get('shared'):
            raise SharedAttributeUpdateNotSupportedOnApic(type=type)

    def _tenant_by_sharing_policy(self, object):
        if not object.get('shared'):
            return self.name_mapper.tenant(None, object['tenant_id'])
        else:
            return apic_manager.TENANT_COMMON

    def _notify_port_update(self, plugin_context, port_id):
        try:
            port = self._core_plugin.get_port(plugin_context, port_id)
            if self._is_port_bound(port):
                self.notifier.port_update(plugin_context, port)
        except n_exc.PortNotFound:
            # Notification not needed
            pass

    def _get_port_network_type(self, context, port):
        try:
            network = self._core_plugin.get_network(context,
                                                    port['network_id'])
            return network['provider:network_type']
        except n_exc.NetworkNotFound:
            pass

    def _is_apic_network_type(self, context, port):
        return (self._get_port_network_type(context, port) ==
                ofcst.TYPE_OPFLEX)

    def _is_port_bound(self, port):
        return port.get(portbindings.VIF_TYPE) not in [
            portbindings.VIF_TYPE_UNBOUND,
            portbindings.VIF_TYPE_BINDING_FAILED]

    def _use_implicit_subnet(self, context, force_add=False):
        """Implicit subnet for APIC driver.

        The first PTG of a given BD will allocate a new subnet from the L3P.
        Any subsequent PTG in the same BD will use the same subnet.
        More subnets will be allocated whenever the existing ones go out of
        addresses.
        """
        l2p_id = context.current['l2_policy_id']
        with lockutils.lock(l2p_id, external=True):
            subs = self._get_l2p_subnets(context._plugin_context, l2p_id)
            subs = set([x['id'] for x in subs])
            added = None
            if not subs or force_add:
                l2p = context._plugin.get_l2_policy(context._plugin_context,
                                                    l2p_id)
                added = super(
                    ApicMappingDriver, self)._use_implicit_subnet(
                        context, mark_as_owned=False,
                        subnet_specifics={'name': APIC_OWNED + l2p['name']})
                subs.add(added['id'])
            context.add_subnets(subs - set(context.current['subnets']))
            if added:
                self.process_subnet_added(context._plugin_context, added)

    def _sync_epg_subnets(self, plugin_context, l2p):
        l2p_subnets = [x['id'] for x in
                       self._get_l2p_subnets(plugin_context, l2p['id'])]
        epgs = self.gbp_plugin.get_policy_target_groups(
            nctx.get_admin_context(), {'l2_policy_id': [l2p['id']]})
        for sub in l2p_subnets:
            # Add to EPG
            for epg in epgs:
                if sub not in epg['subnets']:
                    try:
                        (self.gbp_plugin.
                         _add_subnet_to_policy_target_group(
                             nctx.get_admin_context(), epg['id'], sub))
                    except gpolicy.PolicyTargetGroupNotFound as e:
                        LOG.warn(e)

    def _get_l2p_subnets(self, plugin_context, l2p_id):
        l2p = self.gbp_plugin.get_l2_policy(plugin_context, l2p_id)
        return self._core_plugin.get_subnets(
            plugin_context, {'network_id': [l2p['network_id']]})

    def _configure_implicit_contract(self, context, l2p, transaction=None):
        with self.apic_manager.apic.transaction(transaction) as trs:
            tenant = self._tenant_by_sharing_policy(l2p)
            # Create Service contract
            contract = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=IMPLICIT_PREFIX)
            self.apic_manager.create_contract(
                contract, owner=tenant, transaction=trs)

            # Create ARP filter/subject
            attrs = {'etherT': 'arp'}
            self._associate_service_filter(tenant, contract, 'arp',
                                           'arp', transaction=trs, **attrs)

    def _configure_shadow_epg(self, context, l2p, bd_name, transaction=None):
        with self.apic_manager.apic.transaction(transaction) as trs:
            tenant = self._tenant_by_sharing_policy(l2p)
            shadow_epg = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=SHADOW_PREFIX)
            self.apic_manager.ensure_epg_created(
                tenant, shadow_epg, bd_owner=tenant, bd_name=bd_name,
                transaction=trs)

            # Create Service contract
            contract = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=SERVICE_PREFIX)
            self.apic_manager.create_contract(
                contract, owner=tenant, transaction=trs)

            # Shadow EPG provides this contract
            self.apic_manager.set_contract_for_epg(
                tenant, shadow_epg, contract, provider=True,
                contract_owner=tenant, transaction=trs)

            # Create DNS filter/subject
            attrs = {'etherT': 'ip',
                     'prot': 'udp',
                     'dToPort': 'dns',
                     'dFromPort': 'dns'}
            self._associate_service_filter(tenant, contract, 'dns',
                                           'dns', transaction=trs, **attrs)
            attrs = {'etherT': 'ip',
                     'prot': 'udp',
                     'sToPort': 'dns',
                     'sFromPort': 'dns'}
            self._associate_service_filter(tenant, contract, 'dns',
                                           'r-dns', transaction=trs, **attrs)

            # Create HTTP filter/subject
            attrs = {'etherT': 'ip',
                     'prot': 'tcp',
                     'dToPort': 80,
                     'dFromPort': 80}
            self._associate_service_filter(tenant, contract, 'http',
                                           'http', transaction=trs, **attrs)
            attrs = {'etherT': 'ip',
                     'prot': 'tcp',
                     'sToPort': 80,
                     'sFromPort': 80}
            self._associate_service_filter(tenant, contract, 'http',
                                           'r-http', transaction=trs, **attrs)

            attrs = {'etherT': 'ip',
                     'prot': 'icmp'}
            self._associate_service_filter(tenant, contract, 'icmp',
                                           'icmp', transaction=trs, **attrs)

            # Create DHCP filter/subject
            attrs = {'etherT': 'ip',
                     'prot': 'udp',
                     'dToPort': 68,
                     'dFromPort': 68,
                     'sToPort': 67,
                     'sFromPort': 67}
            self._associate_service_filter(tenant, contract, 'dhcp',
                                           'dhcp', transaction=trs, **attrs)
            attrs = {'etherT': 'ip',
                     'prot': 'udp',
                     'dToPort': 67,
                     'dFromPort': 67,
                     'sToPort': 68,
                     'sFromPort': 68}
            self._associate_service_filter(tenant, contract, 'dhcp',
                                           'r-dhcp', transaction=trs, **attrs)

            # Create ARP filter/subject
            attrs = {'etherT': 'arp'}
            self._associate_service_filter(tenant, contract, 'arp',
                                           'arp', transaction=trs, **attrs)

            contract = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=IMPLICIT_PREFIX)
            # Shadow EPG provides and consumes implicit contract
            self.apic_manager.set_contract_for_epg(
                tenant, shadow_epg, contract, provider=False,
                contract_owner=tenant, transaction=trs)
            self.apic_manager.set_contract_for_epg(
                tenant, shadow_epg, contract, provider=True,
                contract_owner=tenant, transaction=trs)

    def _associate_service_filter(self, tenant, contract, filter_name,
                                  entry_name, transaction=None, **attrs):
        with self.apic_manager.apic.transaction(transaction) as trs:
            filter_name = '%s-%s' % (str(self.apic_manager.app_profile_name),
                                     filter_name)
            self.apic_manager.create_tenant_filter(
                filter_name, owner=tenant, entry=entry_name,
                transaction=trs, **attrs)
            self.apic_manager.manage_contract_subject_bi_filter(
                contract, contract, filter_name, owner=tenant,
                transaction=trs, rule_owner=tenant)

    def _delete_shadow_epg(self, context, l2p, transaction=None):
        with self.apic_manager.apic.transaction(transaction) as trs:
            tenant = self._tenant_by_sharing_policy(l2p)
            shadow_epg = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=SHADOW_PREFIX)
            self.apic_manager.delete_epg_for_network(
                tenant, shadow_epg, transaction=trs)

            # Delete Service Contract
            contract = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=SERVICE_PREFIX)
            self.apic_manager.delete_contract(
                contract, owner=tenant, transaction=trs)

    def _delete_implicit_contract(self, context, l2p, transaction=None):
        with self.apic_manager.apic.transaction(transaction) as trs:
            tenant = self._tenant_by_sharing_policy(l2p)
            contract = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=IMPLICIT_PREFIX)
            self.apic_manager.delete_contract(
                contract, owner=tenant, transaction=trs)

    def _configure_epg_service_contract(self, context, ptg, l2p, epg_name,
                                        transaction=None):
        with self.apic_manager.apic.transaction(transaction) as trs:
            contract_owner = self._tenant_by_sharing_policy(l2p)
            tenant = self._tenant_by_sharing_policy(ptg)
            contract = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=SERVICE_PREFIX)
            self.apic_manager.set_contract_for_epg(
                tenant, epg_name, contract, provider=False,
                contract_owner=contract_owner, transaction=trs)

    def _configure_epg_implicit_contract(self, context, ptg, l2p, epg_name,
                                         transaction=None):
        with self.apic_manager.apic.transaction(transaction) as trs:
            contract_owner = self._tenant_by_sharing_policy(l2p)
            tenant = self._tenant_by_sharing_policy(ptg)
            contract = self.name_mapper.l2_policy(
                context, l2p['id'], prefix=IMPLICIT_PREFIX)
            self.apic_manager.set_contract_for_epg(
                tenant, epg_name, contract, provider=False,
                contract_owner=contract_owner, transaction=trs)
            self.apic_manager.set_contract_for_epg(
                tenant, epg_name, contract, provider=True,
                contract_owner=contract_owner, transaction=trs)

    def _get_redirect_action(self, context, policy_rule):
        for action in context._plugin.get_policy_actions(
                context._plugin_context,
                filters={'id': policy_rule['policy_actions']}):
            if action['action_type'] == g_const.GP_ACTION_REDIRECT:
                return action

    def _validate_new_prs_redirect(self, context, prs):
        if self._prss_redirect_rules(context._plugin_context.session,
                                     [prs['id']]) > 1:
            raise gpexc.MultipleRedirectActionsNotSupportedForPRS()

    def _prss_redirect_rules(self, session, prs_ids):
        if len(prs_ids) == 0:
            # No result will be found in this case
            return 0
        query = (session.query(gpdb.gpdb.PolicyAction).
                 join(gpdb.gpdb.PolicyRuleActionAssociation).
                 join(gpdb.gpdb.PolicyRule).
                 join(gpdb.gpdb.PRSToPRAssociation).
                 filter(
                 gpdb.gpdb.PRSToPRAssociation.policy_rule_set_id.in_(prs_ids)).
                 filter(gpdb.gpdb.PolicyAction.action_type ==
                        g_const.GP_ACTION_REDIRECT))
        return query.count()

    def _multiple_pr_redirect_action_number(self, session, pr_ids):
        # Given a set of rules, gives the total number of redirect actions
        # found
        if len(pr_ids) == 0:
            # No result will be found in this case
            return 0
        return (session.query(gpdb.gpdb.PolicyAction).
                join(gpdb.gpdb.PolicyRuleActionAssociation).
                filter(
            gpdb.gpdb.PolicyRuleActionAssociation.policy_rule_id.in_(pr_ids)).
                filter(gpdb.gpdb.PolicyAction.action_type ==
                       g_const.GP_ACTION_REDIRECT)).count()


text:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Windows;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;

using MS.Internal;
using MS.Win32;

namespace System.Windows.Automation.Peers
{

   ///
   public abstract class ButtonBaseAutomationPeer: FrameworkElementAutomationPeer
    {
        ///
        protected ButtonBaseAutomationPeer(ButtonBase owner): base(owner)
        {}

        ///
        override protected string GetAcceleratorKeyCore()
        {
            string acceleratorKey = base.GetAcceleratorKeyCore();
            if (acceleratorKey == string.Empty)
            {
                RoutedUICommand uiCommand = ((ButtonBase)Owner).Command as RoutedUICommand;
                if (uiCommand != null && !string.IsNullOrEmpty(uiCommand.Text))
                {
                    acceleratorKey = uiCommand.Text;
                }
            }
            return acceleratorKey;
        }

        ///
        protected override string GetAutomationIdCore()
        {
           string result = base.GetAutomationIdCore();
           if (string.IsNullOrEmpty(result))
           {
               ButtonBase owner = (ButtonBase)Owner;
               RoutedCommand command = owner.Command as RoutedCommand;
               if (command != null)
               {
                   string commandName = command.Name;
                   if (!string.IsNullOrEmpty(commandName))
                   {
                       result = commandName;
                   }
               }
           }
           return result ?? string.Empty;
        }

        // Return the base without the AccessKey character
        ///
        override protected string GetNameCore()
        {
            string result = base.GetNameCore();
            ButtonBase bb = (ButtonBase)Owner;
            if (!string.IsNullOrEmpty(result))
            {
                if (bb.Content is string)
                {
                    result = AccessText.RemoveAccessKeyMarker(result);
                }
            }
            else
            {
                RoutedUICommand uiCommand = bb.Command as RoutedUICommand;
                if (uiCommand != null && !string.IsNullOrEmpty(uiCommand.Text))
                {
                    result = uiCommand.Text;
                }
            }
            return result;
        }
    }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kooboo.Web.Mvc.Paging;
using Lucene.Net.Index;

namespace Kooboo.CMS.Search
{
    public interface ISearchService
    {
        void Add<T>(T o);
        void Update<T>(T o);
        void Delete<T>(T o);
        void BatchAdd<T>(IEnumerable<T> list);
        void BatchUpdate<T>(IEnumerable<T> list);
        void BatchDelete<T>(IEnumerable<T> list);
        void BatchDelete(string folderName);

        PagedList<Models.ResultObject> Search(string key, int pageIndex, int pageSize, params string[] folders);
    }
}


text:
<!DOCTYPE html>

    <title>Fandoavam-bola</title>
    <link rel="stylesheet" href="<?= base_url("assets/admin/css/bootstrap.min.css")?>">
    <link rel="stylesheet" href="<?= base_url("assets/default/css/bootstrap-filestyle.min.css")?>">
    <link rel="stylesheet" href="<?= base_url("assets/default/css/custom-register.css")?>">
    <link href="<?= base_url('assets/admin/css/jquery.datetimepicker.css')?>" rel="stylesheet">

Ny Kaomanandy nataonao

Tolotra Gold <?= $duree?> volana

Vidin'ny Tolotra  : <?= $montant?> Ar

    <form action="<?= base_url('usercontroller/ajout')?>" method="post">

Safidy ny handoavam-bola

                <input type="radio" name="mobile" value="autre" autocomplete="off" checked>Autre mode

                <input type="radio" name="mobile" value="airtel" autocomplete="off">Airtel Money(0 33 03 888 56)

                <input type="radio" name="mobile" value="telma" autocomplete="off">M'Vola(0 34 63 705 72)

                <input type="radio" name="mobile" value="orang" autocomplete="off">Orange Money(0 32 86 933 16)

                Nomerao mpandefa
                <input type="text" name="num" placeholder="Nomereo mpandefa" class="form-control" required>

                Trans id
                <input type="text" name="trans_id" placeholder="Transaction id" class="form-control" required>

Fanamarihana

Raha misy ny olana aminy fidiranao ho mpikanbana eto aminay dia azo antsoina avy antrainy ireto laharana ireto:

+261 34 20 300 24

+261 34 03 888 56

Rehefa voamarina fa voaloa tokoa ny vidin'ny tolotra dia hahazo mailaka ianao, hahafantaranao

            <button class="btn btn-info pull-right" type="submit"> Alefa</button>

    </form>


text:
package com.eugenePetrenko.idea.dependencies;

import com.eugenePetrenko.idea.dependencies.data.ModulesDependencies;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderEntry;
import org.jetbrains.annotations.NotNull;

/**
* Created by Eugene Petrenko (eugene.petrenko@gmail.com)
* Date: 17.04.13 12:19
*/
public enum AnalyzeStrategies implements AnalyzeStrategy {
  WITH_EXPORT_DEPENDENCIES {
    @NotNull
    public Module[] collectAllModules(@NotNull Project project, @NotNull Module[] initial) {
      return ModuleDependenciesHelper.includeExportDependencies(project, initial);
    }

    public void updateDetectedDependencies(@NotNull Project project, @NotNull Module[] modules, @NotNull ModulesDependencies deps) {
      ModuleDependenciesHelper.updateExportedDependenciesUsages(project, modules, deps);
    }

    public boolean isSupportedDependency(@NotNull OrderEntry entry) {
      //all supported deps are included
      return true;
    }
  },

  SKIP_EXPORT_DEPENDENCIES {
    @NotNull
    public Module[] collectAllModules(@NotNull Project project, @NotNull Module[] initial) {
      return initial;
    }

    public void updateDetectedDependencies(@NotNull Project project, @NotNull Module[] modules, @NotNull ModulesDependencies deps) {
      //NOP
    }

    public boolean isSupportedDependency(@NotNull OrderEntry entry) {
      return !ModuleDependenciesHelper.isExportDependency(entry);
    }
  }
}


text:
var ajaxInProgress = false;

$(function() {

    // console.log('start');

    var hash = window.location.hash;

    if(hash) {
        try {
            const id = hash.substr(1);
            const yourElement = document.getElementById(id);
            const y = yourElement.getBoundingClientRect().top + window.pageYOffset;
            window.scrollTo({top: y, behavior: 'smooth'});
        } catch(e)
        {
          //catch hash to non existent element. do nothing. #1096
          //   console.log(e);
        }

    }

    $(document).ajaxStart(function() {
        ajaxInProgress = true;
    });

    $( document ).ajaxStop(function() {
        ajaxInProgress = false;
    });

    $('form button[type="submit"]').on('click', function(event) {
        var button = $(this);
        // disable clicked button almost immediately to prevent double click
        setTimeout(function() {
            button.prop('disabled', true);
            // enabled clicked button again after one second
            setTimeout(function() {
                button.prop('disabled', false);
            }, 1000);
        }, 50);
    });

    var adjustUrls = function(event) {

        window.history.replaceState({}, window.document.title, $(event.target).attr('href'));
        $('a[href*="redirect="]').each(function(index, element) {
           $(element).attr('href', $(element).attr('href').replace(/(redirect=)([^&]*)/, '$1'+encodeURIComponent(window.location.href)));
            console.log('Redirect set');
            $(element).attr('href', $(element).attr('href').replace(/(redirect=)([^&]*)/, '$1'+window.location.pathname+window.location.hash));
        });
    };

    // make table rows clickable
    $('table.table.table-hover tr').click(function(event) {
        // do nothing when clicked on a link or input element
        if ('A' == event.target.tagName || $(event.target).is(':input')) {
            return;
        }
        if (typeof($(this).data('href')) != 'undefined') {
            window.document.location = $(this).data('href');
        }
    });

    // navigate to active tab or pill
    $('.nav-tabs a[href="'+window.location.hash+'"]').tab('show');
    $('.nav-pills a[href="'+window.location.hash+'"]').tab('show');

    // adjust urls when activating other tab or pill
    $('.nav-tabs a').on('shown.bs.tab', adjustUrls);
    $('.nav-pills a').on('shown.bs.tab', adjustUrls);

    var filter = $('form.ajaxFilter');
    var lastFilterState = null;
    var postFilterForm = _.debounce(function() {
        var currentFilterState = filter.serialize();
        if (currentFilterState != lastFilterState) {
            lastFilterState = currentFilterState;
            filter.submit();
        }
    }, 300);
    filter > $(':input').on('keyup', postFilterForm);
    filter > $(':input').on('change', postFilterForm);
    filter.submit(function(event) {
        var url = window.location.pathname+'?'+filter.serialize();
        showLoader();
        $.get({
            url: url,
        }).done(function(response) {
            $('#ajaxContainer').html(response);
            hideLoader();
            window.history.replaceState({}, window.document.title, url);
        });
        event.preventDefault();
    });

});

var showLoader = function() {
    $("#ajaxContainer").hide();
    $("#loader").show();
}

var hideLoader = function() {
    $("#loader").hide();
    $("#ajaxContainer").show();
}